[LeetCode]16 最接近的三者之和

3Sum Closest(最接近的三者之和)

【难度:Medium】
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

For example, given array S = {-1 2 1 -4}, and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

给定一整数数组,找到数组中最接近目标值的三个数之和,假设只有唯一解。
如 S={-1,2,1,-4} target = 1
最接近1的三个数之和为2:(-1+2+1=2)


解题思路

在LeetCode 15题中,我们知道了如何去求得三个数之和等于目标值的方法,那么本题则是在15题的基础上进行解决。首先对数组进行排序,可以得到三种基本情况:
1)前三个数之和大于或等于target,那么此时最接近target的三个数之和就是前三个数之和,因为数组是升序的;
2)最后三个数之和小于或等于target,那么此时最接近target的三个数之后就是最后三个数之和,与1)同理;
3)target的值在数组可组成的和区间之内,需要遍历整个数组。此时与15题类似,对于当前的整数nums[i],使用两个下标同时从两边搜索,利用一些数学知识来进行判断。


class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        if (nums.size() < 3)
            return 0;

        insertSort(nums);

        int n = nums.size();
        if (nums[0]+nums[1]+nums[2] >= target)
            return nums[0]+nums[1]+nums[2];
        if (nums[n-3]+nums[n-2]+nums[n-1] < target)
            return nums[n-3]+nums[n-2]+nums[n-1];

        int ans = nums[0]+nums[1]+nums[2];

        for (int i = 0; i < n; i++) {
            int left = i+1;
            int right = n-1;
            while (left < right) {
                int sum = nums[i]+nums[left]+nums[right];
                if (abs(ans-target) > abs(sum-target)) {
                    //sum到target的距离更小
                    ans = sum;
                }
                //此时需要减小sum来减小距离,right左移
                if (sum > target) {
                    right--;
                } else if (sum < target) {
                //此时需要增大sum来减小距离,left右移
                    left++;
                } else {
                //0已是最小距离
                    return sum;
                }
            }

        }
        return ans;
    }
    void insertSort(vector<int>& nums) {
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i-1] > nums[i]) {
                int cur = nums[i];
                int j = i;
                while (j > 0 && nums[j-1] > cur) {
                    nums[j] = nums[j-1];
                    j--;
                }
                nums[j] = cur;
            }
        }
        return;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值