Leetcode-16 最接近的三數之和

題目鏈接
相似題目: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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章