The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are NOT zero-based.
Notice
You may assume that each input would have exactly one solution
Example
numbers=[2, 7, 11, 15], target=9
return [1, 2]
思路
One Solution
如果只需要一对结果: 那么用hashmap的方式来做,时间复杂度最优。
Key: target – currentInt
Value: currentInt_Index
Given: 5, -2, -3, 5, 5. Target = 0
HashMap:
Key, Value
-5, 0
2, 1
3, 2
-5, 3
-5, 4
遍历给定数组,在hashmap找是否其存在。
- 若存在则说明找到了一对满足了要求(currentValue + result = target), Break, 从而避免重复找到自己。
- 返回,currentValue自己的index和 hashmap中currentValue对应的value。
public class Solution {
/*
* @param numbers : An array of Integer
* @param target : target = numbers[index1] + numbers[index2]
* @return : [index1 + 1, index2 + 1] (index1 < index2)
*/
public int[] twoSum(int[] numbers, int target) {
// write your code here
// HashTable
// [2, 7 , 11, 15] target = 9
// [7, 2, -2, -6] ===> remainSet:nunberValue == target - numbers[i]
// [0, 1, 2, 3] ===> remainSet: index
int[] result = new int[2];
if (numbers == null || numbers.length < 2) {
return result;
}
HashMap remainSet = new HashMap<>(); //
// get the remianSet: target - numbers[i]
for(int i = 0; i < numbers.length; i++) {
remainSet.put((target - numbers[i]), i);
}
// find the results
for (int i = 0; i < numbers.length; i++) {
if (remainSet.containsKey(numbers[i])) {
result[0] = i + 1;
result[1] = remainSet.get(numbers[i]) + 1;
break;
}
}
return result;
}
}
No Duplicate All Pairs
如果要找所有结果: 用two pointer的方式,但是需要去重复
比如 -3, -3, -2, -2, 0, 1, 2, 2, 3
此时,-3, 2 , -2, 就需要去重,否则结果出来就会重复
1)需要先排序
2)用head, tail 2个指针,用 where(head
-- 如果 num[head] + num[tail] < target:,则head + +
-- 如果相等说明是答案,记录。
但此时要判重
- 去除做边的重复,比如跳过第二个-3,第二个-2
While(++left < right && num[left] = num[left - 1] {continue;}
- 跳过右边的重复,比如跳过第二个2
While(--right > left && num[right] = num[right + 1] {continue;}
代码
- 如果需要打出所有pair
if (numbers.length == 0 || numbers == null) {
return null;
}
int[] result = new int[2];
int head = 0;
int tail = numbers.length - 1;
List> temp = new ArrayList<>();
Arrays.sort(numbers);
while (head < tail) {
if (numbers[head] + numbers[tail] < target) {
head++;
} else if (numbers[head] + numbers[tail] > target) {
tail--;
} else {
temp.add(Arrays.asList(numbers[head], numbers[tail]));
System.out.print(temp.toString());
while (++head < tail && numbers[head] == numbers[head - 1]) {
continue;
}
while (--tail > head && numbers[tail] == numbers[tail + 1]) {
continue;
}
}
}
return result;
All Pairs
比如1, 1, 1, 3, -1, 2, Target = 4, all pairs就是[1,3],[1,3],[1,3]
方法
- 用hashmap的key存元素本身,value存元素所在的所有index
-1: [4]
1: [0,1,2]
2: [5]
3: [3]
- 如果当前数的remain(target - nuts[i])存在于mapping中,且其value的list不为空,说明找到了solution,结果就是当前数的下标,和remain的所有下标组合
class Solution {
public List> twoSum(int[] nums, int target) {
int[] result1 = new int[2];
if (nums == null || nums.length == 0) {
return result1;
}
// 1. 用hashmap的key存元素本身,value存元素所在的所有index
HashMap> mapping = new HashMap<>();
List> result = new ArrayList<>();
//初始化hashmap
for (int i = 0; i < nums.length; i++) {
mapping.put(nums[i], new ArrayList());
}
//1. 遍历数组,如果当前数的remain存在于mapping中, 且其对用的value size大于0,说明找到了solution,结果就是当前数的下标,和remain的所有下标组合
//2. 将每个元素的下标存入到hashmap中
for (int i = 0; i < nums.length; i++) {
int remain = target - nums[i];
if (mapping.containsKey(remain) && mapping.get(remain).size() > 0) {
for (int j = 0; j < mapping.get(remain).size(); j++) {
result.add(Arrays.asList(mapping.get(remain).get(j), i));
}
}
mapping.get(nums[i]).add(i);
}
return result;
}
}