Q:
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).
哎,一定要看清题啊。题意大致是先给你一个整型数组,然后给你一数target,让你在整型数组中找出三个数,这三个数的和与给定数的差的绝对值最小。
solution:
我看成求三个离给定数最近的数的和呢,闹腾了老半天结果过不了。
这道题的思路是:
- 先对给定的整型数组进行升序排序
- 从头开始遍历该数组,假设当前遍历到第 i 个数,暂时固定i
- 设置两个指针分别是
i+1(j) 一个指向数组尾 (k) ,然后求这两个数组指针所指值与第i个数的和,判断这个和是不是当前target最近的。如果小于,那么j向后移动一位,否则 k 向前移动一位,直到j>=k - i 向前移动一位,重复第3步,直到整型数组全部被遍历
排序的时间复杂度是
这道题是可以进行剪枝的
1.假设当前遍历到
i
,如果
2.如果
num[i]+2∗num[j]−target>abs(currentMins−target)
那么可以跳出循环,j后面的数当前循环不用再遍历。i向后移动一位开始新的循环。
不过这道题的测试结果,剪枝带来的效率提升不大,反而带来了额外的计算量,可能是测试数据与这种剪枝不敏感,所以我就先注释掉了。但是后面有些题这种剪枝很有效果。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int mins =nums[0]+nums[1]+nums[2];
int closestVal = abs(mins-target);
int size = nums.size();
for(int i=0;i<size-1;i++){
if(nums[i]*3-target>closestVal)return mins;
int j = i+1;
int k = size-1;
while(j<k){
//if(nums[i]+nums[j]*2-target>closestVal)break;
int sums = nums[i]+nums[j]+nums[k];
if(sums==target)return sums;
int val=abs(sums-target);
if(val<closestVal){
mins=sums;
closestVal = val;
}
if(sums<target)j++;
else k--;
}
}
return mins;
}
};
Reference Link:
http://blog.youkuaiyun.com/booirror/article/details/44209355