一. 3Sum Closest
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).
Difficulty:Medium
TIME:40MIN
解法
这道题和3Sum几乎是一模一样,但是不同的是这道题不是求刚好等于目标数的结果,而是求和目标数最接近的结果。
处理方式也是如出一辙,但是却稍微有些不同,在考虑这些不同的时候也耗费我大量的时间:
- 由于我们是求最优结果,因此,不管是现在求得的结果比之前最优的结果好还是差,我们都需要移动下标,而且只能移动一边的下标。
- 在while循环内部不应该排除相同的数,既然是求最优的结果,那么就算现在求得结果比之前最优的结果好,也不能保证现在这两个数的其中一个和其他数结合不能够得到更优的结果(因此最多可以排除掉和其中一个数相同的所有数,但不能排除掉两个)。
int threeSumClosest(vector<int>& nums, int target) {
int num = 0;
int dis = INT32_MAX;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 2; i++) {
int left = i + 1;
int right = nums.size() - 1;
while(left < right) {
int sum = nums[left] + nums[right] + nums[i];
if(abs(sum - target) < dis) {
dis = abs(sum - target);
num = sum;
//这里和3Sum有区别的地方就是只能排除掉一边相同的数
while(sum - target < 0 && left + 1 < right && nums[left] == nums[left + 1])
left++;
while(sum - target > 0 && left + 1 < right && nums[right] == nums[right + 1])
right--;
}
if(sum - target < 0)
left++;
else if(sum - target > 0)
right--;
else
return target;
}
if(nums[i + 1] == nums[i]) //这里这样的处理的原因和3Sum是一样的
i++;
}
return num;
}
代码的时间复杂度为 O(n2) 。