Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Analysis
This problem is similar to 2 Sum. This kind of problem can be solved by using a similar approach, i.e., two pointers from both left and right.
Java Solution
public int threeSumClosest(int[] nums, int target) { int min = Integer.MAX_VALUE; int result = 0; Arrays.sort(nums); for (int i = 0; i < nums.length; i++) { int j = i + 1; int k = nums.length - 1; while (j < k) { int sum = nums[i] + nums[j] + nums[k]; int diff = Math.abs(sum - target); if(diff == 0) return sum; if (diff < min) { min = diff; result = sum; } if (sum <= target) { j++; } else { k--; } } } return result; } |
Time Complexity is O(n^2).
sort the array. I think you forgot that step
Do we need to have “=” (sum <= target) here ?? since if its equal the diff will be zero and we will be returning sum.
Looks so. Can You proof that? Thanks.
Wouldn’t it be sufficient if the main loop is iterated only till nums.length-2. Thanks.
Your solution assumes the 3 values must be next to each other, which is not true. E.g. {1,3,5,7} tgt = 13
This doesn’t work for
Input:[1,1,1,0]
Target:100
Output:
2
Expected:3
fixed.
Can be converted to a binary search problem after sorting.
The runtime is NlogN(sorting)+logN(binary search)=NlogN
The code is here: https://github.com/jasonzhang2022/algorithm/blob/master/src/main/java/jason/algorithm/practice/ThreeSumClosest.java
public int threeSumCloset(int[]numbers, int target){
if (numbers == null || numbers.length < 3){
return Integer.MAX_VALUE;
}
int min = Integer.MAX_VALUE / 2;
int result = Integer.MAX_VALUE / 2;
Arrays.sort(numbers);
int length = numbers.length;
for (int i = 0; i numbers[i – 1]){
int start = i + 1;
int end = length – 1;
while (start Math.abs(sum – target)){
min = Math.abs(sum – target);
result = sum;
}
start++;
end–;
while (start < end && numbers[start] == numbers[start – 1]){
start++;
}
while (start < end && numbers[end] == numbers[end + 1]){
end–;
}
}
}
}
return result;
}
}
if(diff == 0) return 0; is wrong, you should return sum instead.
Shouldn’t it be
if(diff == 0) return target;
instead of 0?
Can this be done using c++ implementation, I’m not able to do it …
you should return target if diff equals 0
Not necessarily. Because different combinations can still have the same sum value. An extreme case: given array {1, 1, 1, 1, 1} and target value 1.
Absolutely helpful. Added!
“You may assume that each input would have exactly one solution” Does this mean no duplicates in array?
Hi, good code!
But I think add this line of code:
if (diff == 0) return sum;
behind the code:
int diff = Math.abs(sum – target);
maybe makes the run time shorter?
Like your code. Always short and clean, plus easy to understand following a logic. Thumbs up!