【leetcode】16. 最接近的三数之和。「双指针」

108 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3 -10^3 <= nums[i] <= 10^3 -10^4 <= target <= 10^4

思路:

这道题和三数之和很像,不过要更简单一点,用的也是双指针的思路(三个指针)。首先先固定第一个数然后将后面的范围设定左右边界,然后进行条件判断如果小了就往右移动左边界,大了就往左移动右边界,每次判断都记录下最接近的值存储下来,最后输出最接近组的三数之和就可以了。本题为了优化算法将重复的给排除了,速度快些。

代码区:

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());//首先进行排序,避免重复排列组合
        int i=0;int n=nums.size();int minn=10000;int sum=0;//n为nums数组长度
        while(i<n-1){//i为第一个数,从0开始往后遍历
            int j=i+1;int k=n-1;//j为第二个数,k为第三个数,分别为左右边界
            while(j<k){//当两者没有相遇的时候
                if(abs(nums[i]+nums[j]+nums[k]-target)<minn)//如果和目标值比上一个组合接近的时候就把这几个数的和记录下来,同时替换掉最接近的数
                {
                    minn=abs(nums[i]+nums[j]+nums[k]-target);
                    sum=nums[i]+nums[j]+nums[k];
                }
                if(nums[i]+nums[j]+nums[k]<target){//如果小于目标值的话就右移动左边界,使数变大
                    j++;
                }else if(nums[i]+nums[j]+nums[k]>target){//如果大于目标值的话就左移右边界,使数变小
                    k--;
                }else {//如果和target相等就直接返回三数之和
                    return nums[i]+nums[j]+nums[k];
                }
                while(j<k&&j>i+1&&nums[j]==nums[j-1])//为了避免重复优化算法,这里当出现和上一个数相等的时候就把这个数跳过,但要注意下标条件不要弄错了
                    j++;
                while(j<k&&k<n-1&&nums[k]==nums[k+1])
                    k--;
            }
            i++;
            while(i<n-1&&nums[i]==nums[i-1])//同上,优化算法
                i++;
        }
        return sum;
    }
};

新手上路,有错请指正;