LeetCode 16 最接近的三数之和(数组、双指针)

16 篇文章 0 订阅

题目要求:

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

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

 

 

 

C++代码:

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int n = nums.size();
        
        sort(nums.begin(), nums.end());
        int diff = INT_MAX;
        int ans;
        for(int i = 0; i < n-2; i++)
        {
            int num_i = nums[i];
            int l = i+1, r = n-1;
            
            if (i > 0 && num_i > 0 && num_i > target) return ans;
            
            while(l < r)
            {
                int sum = num_i + nums[l] + nums[r];
                if (diff > abs(sum - target))
                {
                    ans = sum;
                    diff = abs(sum - target);
                }
                if (sum > target) r--;
                else if (sum < target) l++;
                else return sum;
            }
        }
        
        return ans;
    }
};

 

 

 

 

结果(8ms):

 

 

 

解析:

这题跟之前的第15题求三数之和基本一样的思路

LeetCode 15 三数之和(数组、双指针)

多了一个判断当前的sum和target的差的过程而已,因为我们要求最接近的三数之和,越接近越好

 

详细解释如下:

把nums里的元素个数赋给n

int n = nums.size();

然后对nums的元素排序

sort(nums.begin(), nums.end());

然后初始化最大的偏差,这里叫diff,为INT_MAX

int diff = INT_MAX;

然后定义一个ans,就是最后返回的最接近的三数之和

int ans;

然后就是遍历每一个元素,从左到右,已经排好序的,和第15题一样,只遍历到n-2

for(int i = 0; i < n-2; i++)

首先把第一个元素的值赋给num_i

int num_i = nums[i];

然后跟第15题一样,第二个元素取第一个元素的下一位,第三个元素取最后一个元素

int l = i+1, r = n-1;

如果第一个元素都比target大了,那么越加后面的元素,总和越大,直接返回ans即可,ans此时为空

if (i > 0 && num_i > 0 && num_i > target) return ans;

否则,只要l<r,就执行while循环

while(l < r)

计算当前的三数之和sum

int sum = num_i + nums[l] + nums[r];

如果当前的sum和target之差的绝对值abs(sum - target),比前一次的diff小的话,那么我们就需要更新ans和diff

ans更新为当前的sum

diff更新为当前的sum和target之差的绝对值abs(sum - target)

if (diff > abs(sum - target))
  {
         ans = sum;
         diff = abs(sum - target);
  }

然后我们还需要判断我们当前的sum和target直接的关系,看到底是比target大还是比target小,我们好对第二个和第三个元素的位置进行更新,具体还是和第15题一样

if (sum > target) r--;
    else if (sum < target) l++;
    else return sum;

最后注意,该题返回的是int类型的,也就是最接近的三数之和,不需要三个元素,因此最后return ans; 即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值