三数之和(双指针)

题意:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

分析:
从数值的分析上,a+b+c=0一定有数字大于等于0,有数值小于等于0,如果无序,那么暴力枚举各个数O(n3)并且还需要考虑去重

可以采取动静的思路,首先对序列进行排序,三个数字,一个在左面,一个在左面,一个在右面,三个中以其中一个为定点,如果以中间为临时定,左右两个分别从两边向中间指针试探,如果其中遇到相等的即加入结果集。但是这样的一个结果需要去重,因为无法判断唯一,具体实现代码为:

public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> list=new ArrayList<List<Integer>>();Set<String>set=new HashSet<String>();Arrays.sort(nums);for(int i=1;i<nums.length-1;i++){     int left=0;int right=nums.length-1;while (left<i&&right>i) {//System.out.println(i+" "+left+" "+i+" "+right+" "+list.toString());if(nums[left]>0)break;int sum=nums[left]+nums[i]+nums[right];//System.out.println(nums[left]+" "+nums[i]+" "+nums[right]);if(sum==0){String teamString=nums[left]+" "+nums[i]+" "+nums[right];if(!set.contains(teamString)) {List<Integer>list2=new ArrayList<Integer>();list2.add(nums[left]);list2.add(nums[i]);list2.add(nums[right]);list.add(list2);set.add(teamString);}left++;right--;}else if (sum>0) {right--;}else {left++;}}}return list;  }

而如果循环一次每次确定左侧的,中间的和右侧的分别向右侧和左侧拓展,那么这样可以实现一个去重,并且时间复杂度为O(n2)但需要注意以下细节:

  • 当前最左侧数字sums[i]如果和sums[i-1](i>1)相等,那么跳出本次计算,因为当前数字如果作为最左侧数字那么前面有相同的数字可以组成这个集合,所以不需要这部的计算
  • 同时在确定最左侧,中间left和最右侧right向中间进行时如果三数之和大于0,那么right–;如果三数之和小于0,那么left++;同时你可以进行部分剪枝优化,把不可能的情况直接过滤掉。

ac代码为:

 public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> list=new ArrayList<List<Integer>>();Arrays.sort(nums);for(int i=0;i<nums.length-2;i++){  int left=i+1;int right=nums.length-1;if(i>0&&nums[i]==nums[i-1])continue;while (left<right) {//System.out.println(i+" "+left+" "+i+" "+right+" "+list.toString());if(nums[left]+nums[i]>0)break;int sum=nums[left]+nums[i]+nums[right];//System.out.println(nums[left]+" "+nums[i]+" "+nums[right]);if(sum==0){List<Integer>list2=new ArrayList<Integer>();list2.add(nums[i]);while (left<right&&nums[left]==nums[left+1]) {left++;}list2.add(nums[left]);while (left<right&&nums[right]==nums[right-1]) {right--;}list2.add(nums[right]);list.add(list2);left++;right--;} else if (sum>0) {right--;}else {left++;}}}return list;}

最接近的三数之和

题意:
给定一个包括 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

分析:
有了上题的思路,本题依然使用双指针,不过最接近sum需要你用数字记录它的大小并且还需要考虑正负的问题。

具体的处理上,和上一题整体思想一致,首先排序,循环一次确定最左侧的,这层为O(n),同时每个最左侧确定之和中间和右侧分别向中间靠拢,如果三数之和大于target,那么right–,否则left++,同时要和最接近的数进行比较是否更接近,这样执行完毕即可获得最接近target的三个数字之和。

具体实现代码为:

 public static int threeSumClosest(int[] nums, int target) { Arrays.sort(nums);int value=nums[0]+nums[1]+nums[2];for(int i=0;i<nums.length-2;i++){   int left=i+1;int right=nums.length-1;while (left<right) {int sum=nums[left]+nums[i]+nums[right];int gap1=Math.abs(value-target);int gap2=Math.abs(sum-target);if(target>=0&&nums[left]+nums[i]-target>gap1)break;if(gap2<gap1){value=sum;} if (sum==target) {return target;}else if(sum>target) {right--;}else {left++;}  }}return value;}

结语

原创不易,bigsai请你帮两件事帮忙一下:

  1. star支持一下, 您的肯定是我在平台创作的源源动力。

  2. 微信搜索「bigsai」,关注我的公众号,不仅免费送你电子书,我还会第一时间在公众号分享知识技术。加我还可拉你进力扣打卡群一起打卡LeetCode。

记得关注、咱们下次再见!

LeetCode 15三数之和16最接近的三数之和相关推荐

  1. Leetcode算法Java全解答--16. 最接近的三数之和

    Leetcode算法Java全解答–16. 最接近的三数之和 文章目录 Leetcode算法Java全解答--16. 最接近的三数之和 题目 想法 结果 总结 代码 我的答案 暴力破解 滑动列表 大佬 ...

  2. LeetCode15. 三数之和 16. 最接近的三数之和

    LeetCode15. 三数之和 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组 ...

  3. Java实现 LeetCode 16 最接近的三数之和

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

  4. leetcode 16. 3Sum Closest | 16. 最接近的三数之和(双指针)

    题目 https://leetcode.com/problems/3sum-closest/ 题解 方法1:固定 L,双指针找 M.R 时间复杂度 O(n^2),推荐此方法. 证明不会有元素遗漏,详见 ...

  5. leetcode —— 16. 最接近的三数之和

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

  6. LeetCode 16. 最接近的三数之和(固定左端+滑动窗口)

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

  7. leetcode 16.最接近的三数之和

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

  8. LeetCode 16. 最接近的三数之和 3Sum Closest

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

  9. 3. Leetcode 16. 最接近的三数之和 (数组-双向双指针)

    给你一个长度为 n 的整数数组 nums 和 一个目标值 target.请你从 nums 中选出三个整数,使它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在恰好一个解.示例 1: ...

最新文章

  1. leetcode每日一题系列——881. 救生艇
  2. Linux(1)---常用命令
  3. 表的插入、更新、删除、合并操作_6_通过多表关联插入
  4. Mysql的float double decimal
  5. openssl工具的使用以及创建私有CA
  6. 攻略:需求评审怎样才能高效易懂?
  7. 云计算概况及第一个Azure程序
  8. 怎么让手机变成震动器_手机厂商都在说的线性马达,到底是个什么东西?
  9. 1283 最简单的计算机
  10. 数据库关于group by 两个或以上条件的分析
  11. LFW人脸数据集测试协议及编程实现
  12. 小米adb驱动_腾讯口袋阅、小米多看等电子阅读器如何安装第三方软件!
  13. 登录爬取拉勾网2.0 Python selenium
  14. String StringBuffer StringBuild区别?
  15. 大学计算机课程学习路线 左飞老师
  16. 风袖电商之重构Theme业务对象
  17. excel中为什么不显示单引号
  18. 有主力资金活跃迹象的三大板块
  19. linux wine 使用教程,Wine 使用技巧两则
  20. 高山养羊也可以运用GPS卫星定位系统

热门文章

  1. C++ Primer 5th笔记(chap 12 动态内存)weak_ptr
  2. java结丹期(12)----javaweb(servletHTTPweb相关基本概念)
  3. CTF Re-Python z3库的使用
  4. DRF框架—序列化器中的字段校验规则
  5. linux kernel中的cmdline的详细介绍
  6. 2022-01-23
  7. 【dfs】P1036 选数
  8. php内核分析-fpm和df的问题思考
  9. win7更新powershell到5.1
  10. 4、使用PreparedStatement接口实现增,删,改操作(常用)