題目鏈接
相似題目:Leetcode-15 三數之和
排序+雙指針
對數組nums排序,鎖定一個數字nums[i],再使用雙指針考慮剩下的兩數之和
雙指針初始化:lf=i+1(不用再從頭開始,如果有這個組合在i更小就會被發現的)
對於每一個ans取值,比較res和ans誰和target差絕對值更小.
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int res=INT_MAX/2;
int lf,rt;
for(int i=0;i<nums.size();i++)
{
lf=i+1;
rt=nums.size()-1;
while(lf<rt)
{
int ans=nums[i]+nums[lf]+nums[rt];
if(ans==target)
{
return target;
}
else if(ans<target)
{
res=fabs(res-target)>fabs(ans-target)?ans:res;
lf++;
}
else
{
res=fabs(res-target)>fabs(ans-target)?ans:res;
rt--;
}
}
}
return res;
}
};
考慮去重
對於nums[i]的去重
當i比較小時,剩下兩個數的考慮範圍是更大的。
比如對於[1,1,1,2,3],target=7
這一組來講,對於第一個1,便會從[1,1,2,3]
中找到最合適的[2,3]
,第二個1和第三個1只是搜索的範圍在減小,所以可以考慮去重。
對於nums[lf]與nums[rt]的去重
同理,假設輸入變爲[1,1,1,3,3,3],target=6
.
對於第一個1,在[1,1,3,3,3]
中查到的第一組便是nums[lf]=1, nums[rt]=3
之後搜索範圍向內收緊,但是如果nums[lf]或是nums[rt]值與上一次不變,那麼就沒必要再次加和求ans,只有變化值纔有可能帶來更接近的結果
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int res=INT_MAX/2;
int lf,rt;
for(int i=0;i<nums.size();i++)
{
if(i>0&&nums[i-1]==nums[i])
continue;
lf=i+1;
rt=nums.size()-1;
while(lf<rt)
{
int ans=nums[i]+nums[lf]+nums[rt];
if(ans==target)
return target;
res=fabs(res-target)>fabs(ans-target)?ans:res;
if(ans<target)
{
lf++;
while(lf<rt&&nums[lf]==nums[lf-1])
lf++;
}
else
{
rt--;
while(lf<rt&&nums[rt]==nums[rt+1])
rt--;
}
}
}
return res;
}
};