题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
- 暴力法
只要for循环遍历三次,就可以得到答案了,但是这个耗时有点长
为此我采用第二种方法,双指针法 - 双指针法
先一次for循环遍历,然后在剩下的元素中采用双指针来选择
代码如下:
public List<List<Integer>> threeSum(int[] nums) {
//排序
Arrays.sort(nums);
List<List<Integer>> rs = new ArrayList<>();
for (int k=0;k<nums.length;k++){//遍历数组
//因为已经排过序,所以后面的数不会比前面的小,
//所以如果当前的数字大于0,则证明不可能存在三个数的和等于0
if (nums[k]>0) break;
//跳过重复元素,避免重复结果
if (k>0&&nums[k]==nums[k-1]) continue;
//i为左指针,j为右指针
int i=k+1,j=nums.length-1;
while (i<j){
//计算当前三个数的和
int sum = nums[k]+nums[i]+nums[j];
if (sum<0){
//sum小于0,则应该左指针右移
//移动的同时跳过相同元素
while (i<j&&nums[i]==nums[++i]);
}else if (sum>0){
//sum大于0,则应该右指针左移
//跳过相同元素
while (i<j&&nums[j]==nums[--j]);
}else {
//若sum刚好为0,则添加进列表
rs.add(new ArrayList<Integer>(Arrays.asList(nums[k],nums[i],nums[j])));
//同时跳过相同元素
while (i<j&&nums[i]==nums[++i]);
while (i<j&&nums[j]==nums[--j]);
}
}
}
return rs;
}