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