力扣 -- 16. 最接近的三数之和

题目链接:16. 最接近的三数之和 - 力扣(LeetCode) 

具体思路:先把数组按升序的方式排好,利用数组的前三个数先算出一个与target的差距值Closest。外层循环按顺序先选定第一个数,然后在内循环里面定义left和right下标,通过左右下标遍历剩下的数,每选到begin和end对应的数就和第一个数加到一起求和得到threeSum,比较threeSum与target的差距是否比Closest与target的差距值更小,如果更小就更新Closest为threeSum;更新完之后再检查threeSum,如果threeSum比target大,那证明right对应的数选大了(前面已经排好序),那就right--,left不变;如果threeSum比target小,那证明left对应的数选小了,那就left++,right不变;直到left==right就完成了一次循环;中途如果遇到threeSum==target,那就直接返回了,这是最好的结果。

以下是参考代码,已经配上详细的注释,相信各位小伙伴们都能很轻易地看懂并掌握这道题哦。

时间复杂度:O(N^2),空间复杂度O(1)

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        //先把数组排好序,方便后面的选数
        sort(nums.begin(), nums.end());

        //先利用数组的前三个元素定一个最接近的三数之和
        //切记不能随意赋予一个不属于数组中的值,因为这回影响结果
        int Closest = nums[0] + nums[1] + nums[2];

        int i = 0;
        //外层循环选的是第一个数,所以最多选到倒数第三个数即可
        for (i = 0; i < nums.size() - 2; i++)
        {
            //利用左右下标选第二个和第三个数
            int left = i + 1;
            int right = nums.size() - 1;

            //左下标left不能超过右下标right,等于也不用算上,因为同一个数字
            //不能选两次
            while (left < right)
            {
                //计算三数之和
                int threeSum = nums[i] + nums[left] + nums[right];
                
                //比较新算出的threeSum与target的差距与原来的最小差距
                //如果更小就更新Closest
                if (abs(threeSum - target) < abs(Closest - target))
                {
                    Closest = threeSum;
                }

                //算出的三数之和如果比target小,说明left位置的数选小了,需要
                //left++来尽可能地缩小threeSum和target的差距(数组是升序)
                if (threeSum < target)
                {
                    left++;
                }

                //算出的三数之和如果比target大,说明right位置的数选大了,需要
                //right--来尽可能地缩小threeSum和target的差距(数组是升序)
                else if (threeSum > target)
                {
                    right--;
                }

                //如果threeSum==target,那这个threeSum就是最接近target的了
                //直接返回即可
                else
                {
                    return threeSum;
                }
            }

        }

        //如果没有出现threeSum==target的情况,那么这个记录的Closest就是
        //数组中任意选择三个数相加与target差距值最小的结果了,返回Closest
        return Closest;

    }
};

以上就是这道题的一个简单的解法,你学会了吗?如果对你有所帮助,那么请点个小心心,顺便点点关注呗,后期还会持续更新力扣的经典题目哦,我们下期见!!!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值