承接上一题,也是经典的3Sum,计算sum到target最近的距离,今天有点事情有点忙,没有认真做,先做了一个暴力解决的,效率很低(因为test集数据量很小,所以ac了),自己试着优化了一下,边界判断出了点问题。明天早上优化,以后刷题不能放在晚上啊。最近看《模式识别》,感觉第二章有点难懂,都是模型问题,很基础的数学问题了。
计划都没完成,共勉吧。
class Solution {
public:
static int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int min_ans = abs(nums[0]+nums[1]+nums[2]-target);
int ans = nums[0]+nums[1]+nums[2];
for(int i=0; i<nums.size()-2;i++){
if(nums[i]+nums[i+1]+nums[i+2]>target && abs(nums[i]-target) > min_ans) break;
int st=i+1, la=(int)nums.size()-1;
while(st<la){
while(la > st){
if(abs(nums[i]+nums[st]+nums[la]-target) < min_ans){
min_ans = abs(nums[i]+nums[st]+nums[la]-target);
ans = nums[i]+nums[st]+nums[la];
}
la--;
}
la = (int)nums.size()-1;
st++;
}
}
return ans;
}
};
下面是我看到的解法,设定了几个循环截止条件,我觉得想法很好。
就是对第一个量循环时,去找第二、三个量的时候用双指针得到一个front(<target)/behind(>target)【若得到=target则直接return】,然后更新最接近的量。
但是其实可以对第一个量也设定终止条件的。
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
int result = nums[0] + nums[1] + nums[n - 1];
int minValue = abs(target - result);
int front = nums[0] + nums[1] + nums[2];
int behind = nums[n - 3] + nums[n - 2] + nums[n - 1];
for(int i = 0; i < n - 2;){
for(int j = i + 1, k = n - 1; j < k;){
while(j < k && nums[i] + nums[j] + nums[k] < target){
front = nums[i] + nums[j] + nums[k];
++j;
}
while(j < k && nums[i] + nums[j] + nums[k] > target){
behind = nums[i] + nums[j] + nums[k];
--k;
}
if(j < k && nums[i] + nums[j] + nums[k] == target)
return target;
int frontTemp = abs(target - front);
int behindTemp = abs(target - behind);
if(min(frontTemp, behindTemp) < minValue){
if(frontTemp < behindTemp)
result = front;
else
result = behind;
minValue = abs(target - result);
}
}
while(++i < n - 2 && nums[i] == nums[i - 1]);
}
return result;
}