N sum question from leetcode and lintcode
1 two sum(1) Use HashMap to store (nums[i] , index); time O(n) space O(n)
one loop scan to find in map target - num[i] , if exist and index2 != index1( this is important for [3,2,4] return [2,4] not [1,1] ) , return;
else not find
(2) two pointer, but need to store original index
use two pointer , we need to sort array firstly, but the problem is that we need return index not the value.
Solution: this has different way to implement, can write a pair class or copy original array to store index
My code here use array copy idea
// version one
public int[] twoSum(int[] numbers, int target) {
int res[] = new int[2];
int sortarr[] = new int[numbers.length];
sortarr = numbers.clone();
Arrays.sort(sortarr);
//two pointer
int start = 0;
int end = numbers.length -1;
while(start + 1 < end){
if(sortarr[start] + sortarr[end] == target){
break;
}else if(sortarr[start] + sortarr[end] < target){
start++;
}else{
end--;
}
}
if(sortarr[start] + sortarr[end] == target || (start + 1 != end)){
//find index , in case same value
for(int i = 0; i< numbers.length; i++){
if(numbers[i] == sortarr[start] && res[0] == 0){// res[0] not set yet
res[0] = i + 1;
}else if(numbers[i] == sortarr[end]){
res[1] = i + 1;
}
}
}
Arrays.sort(res);
return res;
}
//code use extra class to implement
3 Sum
find three numbers a + b + c = 0 in an array here may exists duplicate numbers need to filter duplicates
[-2, 0, 0, 2,2], the expected output should be [-2,0,2].
If no filter here, the output will be duplicate as [-2,0,2] and [-2,0,2]
If no filter here, the output will be duplicate as [-2,0,2] and [-2,0,2]
Solution :
Two pointer
one loop get numbers[i] ( skip duplicate) , then use two pointer start = i+ 1, end = n -1;
find triplets num[i] + num[start] + num[ end] == 0
(if sum == 0) start++, end-- (
Here: we also need skip duplicate numbers)
Code
3 Sum Closet
just return closet sum value to target
similar to 3 Sum Question, just keep a variable min to record closet sum
update if( |target - sum | < |target - min| ) min = sum;
One need to pay attention here, is we can assign res = Integer.MAX_VALUE / 2 to avoid overflow when | target - min|
Code
4 Sum
find four number whose sum = 0,
similar to 3 sum question, but here we need fix two number: num[i] , num[ j ] (j start from i + 1), then use two pointer to locate another two number
K sum
extend the question to k number
(i )If will only need to return the number of possible solutions, this would be a DP Question.
f[ i ][ j ][ t ] 前 i 个数里, 挑出 j 个数, 组合和为t 有多少种方案
f[ i ][ j ][ t ] = f[ i-1 ][ j-1 ][ t- A[i]] + f[ i-1][ j ][ t ];
return f[ n ][ k ][ target ]
return f[ n ][ k ][ target ]
initial :
f[0][0][0] = 1;
f[0][>0][?] = 0;
f[0][0][0] = 1;
f[0][>0][?] = 0;
(ii) if return all result list, extend from solution for 4 sum