Given an array of integers, find two numbers such that they add up to a specific target number.
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.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
TwoSum属于常识性的题目,也是其他相关3sum,3 sum closest等题目的基础。所以一定要会写。主要方法有brute force,hash table和sort这几种方法。
最简单的方法是brute force,对任意一对组合进行遍历,检查是否等于target。Time complexity O(n2); Space complexity O(1)。可以先问考官是否可以brute force方法解决,因为有些时候要求space complexity尽量小。square面试时出现过这样的情况。
// Brute force: Time complexity O(n2); Space complexity O(1)
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
if (numbers == null || numbers.length < 2){
return res;
}
int len = numbers.length;
for (int i = 0; i < len; i++){
for (int j = i + 1; j < len; j++){
if(numbers[i] + numbers[j] == target){
res[0] = i+1;
res[1] = j+1;
return res;
}
}
}
return res;
}
第二种方法就是hashtable,Time complexity O(n); Space complexity O(n)。实现起来没有任何难度。
// Hashtable: Time complexity O(n); Space complexity O(n)
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
if(numbers == null || numbers.length < 2){
return res;
}
Hashtable<Integer, Integer> ht = new Hashtable<Integer, Integer>();
for (int i = 0; i < numbers.length; i++){
if(ht.containsKey(target-numbers[i])){
res[0] = ht.get(target-numbers[i]) + 1;
res[1] = i + 1;
return res;
}else{
ht.put(numbers[i],i);
}
}
return res;
}
第三种方法是利用sort,先对array从小到大进行排序,然后从左右开始遍历,当左加右小于target的时候做变指针往右移,反之右边指针往左移。需要注意的是本题要求返回的是index,所以需要先copy array,找到符合要求的element以后再在原array中查询,找回对应的index。Time complexity O(nlogn+n) = O(nlogn); Space complexity 取决于用的那种sort方法。Quick sort: O(logn); Merge sort: O(n)
// Sort: Time complexity O(nlogn+n) = O(nlogn); Space complexity depends on the sort algorithm
// Quick sort: O(logn); Merge sort: O(n)
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
if (numbers == null || numbers.length < 2){
return res;
}
int[] copyArray = new int[numbers.length];
for(int i = 0; i < numbers.length; i++){
copyArray[i] = numbers[i];
}
Arrays.sort(copyArray);
int left = 0;
int right = copyArray.length - 1;
while(left < right){
if(copyArray[left] + copyArray[right] < target){
left++;
}else if(copyArray[left] + copyArray[right] > target){
right--;
}else{
res[0] = copyArray[left];
res[1] = copyArray[right];
break;
}
}
int first = -1;
int second = -1;
for(int i = 0; i < numbers.length; i++){
if(numbers[i] == res[0] && first == -1){
first = i+1;
}else if(numbers[i] == res[1] && second == -1){
second = i+1;
}
}
res[0] = first;
res[1] = second;
Arrays.sort(res);
return res;
}