图解LeetCode16:最接近的三数之和(递归和排序+双指针)

LeetCode16:最接近的三数之和

给你一个长度为n的整数数组nums和一个目标值target。请你从nums中选出三个整数,使它们的和与target最接近。

返回这三个数的和。

家丁每组输入只存在恰好一个解。

示例:

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

思路:

这个题目与LeetCode15:三数之和,不能说是一摸一样吧,只能说是丝毫不差。在三数之和中,是找到三数之和为零的那三个数字,而对于这道题,就是找到最接近target的那三个数,如果target=0,那么就是找到最可能是三数之和的那个数,这样一来就很相似了。

在这里插入图片描述

想要找到最终的结果,两者只有这样一个区别

在这里插入图片描述

解法:

因为和三数之和的题目不同,这道题有个前提,假定只有一个解,所以对于LeetCode15不能使用的暴力递归,在这里就可以使用,只是时间复杂度为O(n^3)

解法1:暴力递归

使用三个循环,找到三数之和与target差值最小的那一组就行,使用三个循环
在这里插入图片描述

不断的更新指针,三个循环遍历数组,得到min(min, a+b+c-target),然后保存差值最小的数组
在这里插入图片描述

解法2:排序+双指针

就和上述LeetCode15:三数之和,的解法一样了,将数组排完序之后,使用双指针得到三数之和与targt的差值最小值,得到结果。

①首先将给出的数组排序,按照从高到低,这样一来,对于一串数字,通过判断与target的大小,就可以采用前后同时遍历的方法

②使用两个指针,一个初始在列表开头,另一个初始在列表结尾,然后遍历中间数字相加
在这里插入图片描述

③如果a+b+c>target,那么将尾指针左移一个

④如果a+b+c<=target,将首指针右移一个
在这里插入图片描述

⑤每次遍历都更新min(min, abs(a+b+c-target))的值,如果abs(a+b+c-target)更小,则记录
在这里插入图片描述
⑥逐渐遍历移动指针,直到全部结束
在这里插入图片描述

全部流程
在这里插入图片描述

代码实现

public int threeSumClosest(int [] nums, int target){
    // 排序数组
    Arrays.sort(nums);
    // 初始化结构
    int res = nums[0] + nums[1] + nums[2];
    // 开始遍历
    for(int i = 0; i < nums.length; i++){
        // 声明双指针
        int L = i + 1, R = nums.length - 1;
        // 只要左指针不大于右指针,就可以遍历
        while(L < R){
            // 三数之和
            int sum = nums[L] + nums[i] + nums[R];
            // 更新res
            res = Math.min(res, Math.abs(sum - target))
            // 判断三数之和与target大小,然后相应指针移动
            if(sum > target) R--; else if(sum < target) L ++; else return res;
        }                                  
    }
    return res;
}

测试代码

public static void main(String[] args){
	LeetCode16 lc = new LeetCode16();
	Sysout.out.println(lc.threeSumClosest({-1,-5,2,4,0}, 1));
}

结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牧码文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值