力扣15(Java)-三数之和(中等)
题目:
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
- 3 <= nums.length <= 3000
- -105 <= nums[i] <= 105
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
双指针
参考:代码随想录的文字讲解 && 代码随想录的视频讲解
- 需要求的是数字而不是索引,可以先将数组排序,利用一层for循环,从下标0开始遍历数组元素,即nums[i],再定义双指针从left = i+1,right = nums.length - 1开始往中间靠拢,寻找sum = nums[i] + nums[left] + nums[right]
- 如果sum > 0, 说明和大了,应该减小,则移动右指针使其数字变小,即right--;
- 如果sum < 0,说明和小了,应该增大,则移动左指针使其数字变大,即left++;
- 如果sum == 0, 说明找到了一个符合题意的三元组,即加入结果集。
细节问题:
①答案中不应该包含重复的三元组[三元组内的数字可以重复],如果nums[i]有重复的应该在怎么去重,是判断nums[i] == nums[i+1] 还是nums[i] == nums[i-1]的时候跳过当前数字呢?
例如:示例1中的nums = [-1,0,1,2,-1,-4],排序后nums = [-4,-1,-1,0,1,2]
- 如果判断 nums[i] == nums[i+1] 的时候跳过:nums[1] == nums[2],有[-1,-1,2]和[-1,0,1]这两个符合要求的三元组,这时候跳过,下一步遍历到nums[2]== -1时,就只有[-1,0,1],总体就会跳过[-1,-1,2这个符合要求的三元组。
- 如果判断 nums[i] == nums[i-1] 的时候跳过:遍历到nums[1] == -1的时候有[-1,-1,2]和[-1,0,1]这两个符合要求的三元组,下一步遍历到nums[2]== -1时,nums[2] == nums[1]时,就有[-1,0,1]这时候与nums[1]得到的三元组重复了,就需要跳过了。
②左右指针的去重应该放在找到第一个三元组之后去重:例如:[0,0,0,0,0]
如果按照下面这样写,那么就不会得到任何一个满足条件的三元组,但是实际上是有一个符合条件的三元组的[0,0,0],所以bc的去重应该写在得到第一个符合要求的三元组后面。
while (left < right){
//如果将bc去重逻辑放在while后面
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
.....
}
代码:
1 class Solution {
2 public List<List<Integer>> threeSum(int[] nums) {
3 ArrayList<List<Integer>> ans = new ArrayList<>();
4 Arrays.sort(nums);
5 for (int i = 0; i < nums.length; i++){
6 //如果第一个数(最小的数)都大于0,后面相加只会更大不会等于0
7 if (nums[i] > 0) return ans;
8 //去重,避免重复的三元组
9 if (i > 0 && nums[i] == nums[i-1]) continue;
10 int left = i + 1, right = nums.length - 1;
11 while (left < right){
12 int sum = nums[i] + nums[left] + nums[right];
13 //如果和大于0,让和减小移动右指针
14 if (sum > 0){
15 right--;
16 }else if (sum < 0){
17 //和小于0,让和变大,移动左指针
18 left++;
19 }else{
20 //和等于0,找到一个三元组添加进结果
21 ans.add(Arrays.asList(nums[i], nums[left], nums[right]));
22 //去除左右指针后面和前面的重复元素,例如[-1,-1,-1,0,1,1,1]
23 while (left < right && nums[left] == nums[left + 1]) left++;
24 while (left < right && nums[right] == nums[right - 1]) right--;
25 left++;
26 right--;
27 }
28 }
29 }
30 return ans;
31 }
32 }
小知识:
Arrays.asList(): 该方法是将数组转化成List集合的方法。
- 用此方法得到的List的长度是不可改变的;
- 不支持add()、remove()、clear()等方法;
- 将数组转换为ArrayList:List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
力扣15(Java)-三数之和(中等)的更多相关文章
- 【LeetCode】15. 3Sum 三数之和
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:3sum, 三数之和,题解,leetcode, 力扣,P ...
- [LeetCode] 15. 3Sum 三数之和
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- LeeCode数组第15题三数之和
题目:三数之和 内容: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中 ...
- 【LeetCode】15、三数之和为0
题目等级:3Sum(Medium) 题目描述: Given an array nums of n integers, are there elements a, b, c in nums such t ...
- LeetCode 第15题-三数之和
1. 题目 2.题目分析与思路 3.思路 1. 题目 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且 ...
- [leetcode]15. 3Sum三数之和
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find ...
- 力扣 ——4Sum (四数之和)python 实现
题目描述: 中文: 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 targe ...
- Leetcode(15)-三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- leetcode 刷题(数组篇)15题 三数之和 (双指针)
很有意思的一道题,值得好好思考,虽然难度只有Mid,但是个人觉得不比Hard简单 题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b ...
- 【LeetCode 15】三数之和
题目链接 [题解] 先把n个数字升序排个序. 然后枚举三元组最左边的那个数字是第i个数字. 之后用两个指针l,r移动来获取三元组的第2个和第3个数字. (初始值,l=i+1,r = n-1); 如果a ...
随机推荐
- base-table 加入动态slot 流程 vue2
columns { title: '字段标题', slot: 'yourSlotName', minWidth: 50, align: 'center' }, 组件内 props: { columns ...
- 1.JAVA中的几种基本数据类型是什么,各自占用多少字节
1.JAVA中的几种基本数据类型是什么,各自占用多少字节 基本类型 大小 最小值 最大值 默认值 byte(位) 8bits = 1字节 -128 127 0 short(短整数) 16bit = 2 ...
- 恒玄科技BES2500芯片OTA升级调试总结和源码分析
一 前言 bes2500芯片在tws耳机应用十分广泛,该芯片有着资源强大,音质好,大厂背书等特色.吸引了不少粉丝跟随. 最近在调试该芯片的ota功能,花费了一些时间,踩了一些坑,这里做一个总结和备忘吧 ...
- HTML(表格、列表、表单)
表格 表格的主要作用 1.表格主要用于显示.展示数据,因为它可以让数据显示的非常的规整,可读性非常好.特别是后台展示数据的时候,能够熟练运用表格就显得很重要.一个清爽简约的表格能够把繁杂的数据表现得很 ...
- 开源一个教学型分库分表示例项目 shardingsphere-jdbc-demo
在笔者心中,消息队列,缓存,分库分表是高并发解决方案三剑客. 分库分表之所以被广泛使用,因为工程相对简单,但分库分表并不仅仅是分片,还是需要考虑如何扩缩容(全量同步.增量同步.数据校验等). 因此笔者 ...
- LOTO示波器电源环路增益分析客户实测
我们在之前有文章介绍过LOTO示波器+信号源扫频测电源环路增益稳定性的方法和过程,可以参考演示视频如下: https://www.ixigua.com/7135738415382790663?logT ...
- SpringBoot项目 前后端分离 ajax附件上传下载
前台界面 上传 下载 前台代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- [apue] 进程控制那些事儿
进程标识 在介绍进程的创建.启动与终止之前,首先了解一下进程的唯一标识--进程 ID,它是一个非负整数,在系统范围内唯一,不过这种唯一是相对的,当一个进程消亡后,它的 ID 可能被重用.不过大多数 U ...
- 【非插件实现】wordpress网站页脚添加,网站总访问数/今日访客数
1 /** 2 * 统计全站总访问量/今日总访问量/当前是第几个访客 3 * @return [type] [description] 4 */ 5 function wb_site_count_us ...
- 【直播回顾】如何成为一名优秀的OpenHamrony贡献者?
5月18日晚上19点,战"码"先锋第一期直播<如何成为一名优秀的OpenHamrony 贡献者?>,在OpenHarmony社群内成功举行. 本期课程,由润和资深软件开 ...