题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
提示:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
代码
package tencent50;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class leetcode15 {
// 双指针
// 经典定一个点,然后通过双指针的方式找另两个点的题目,多了去重操作
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ansList = new ArrayList<>();
int len = nums.length;
Arrays.sort(nums);
for (int i = 0; i < len -2; i++){
// 数组有序,所以如果nums[i]>0 i之后的元素也都大于0,则不会存在三数之和为0的情况
if (nums[i] > 0){
break;
}
// 去重
if (i > 0 && nums[i] == nums[i - 1]){
continue;
}
// 双指针,开始找与nums[i]相加和为0的nums[l]、nums[r]
int l = i + 1, r = len - 1;
while (l < r){
int sum = nums[l] + nums[i] + nums[r];
if (sum < 0){
// 左指针右移,同时去重
while (l < r && nums[l] == nums[++l]){
}
// 如下写会时间超限
// l++;
// while (l < r && nums[l] == nums[l + 1]){
// l++;
// }
}
else if (sum > 0){
// 右指针左移
while (l < r && nums[r] == nums[--r]){
}
// r--;
// while (l < r && nums[r] == nums[r - 1]){
// r++;
// }
}
else {
// 满足条件,加入队列中
List<Integer> tmpList = new ArrayList<>();
tmpList.add(nums[i]);
tmpList.add(nums[l]);
tmpList.add(nums[r]);
ansList.add(tmpList);
// 移动l,r到下一个位置,继续寻找满足条件的点
while (l < r && nums[l] == nums[++l]){
}
while (l < r && nums[r] == nums[--r]){
}
// l++;
// while (l < r && nums[l] == nums[l + 1]){
// l++;
// }
// r--;
// while (l < r && nums[r] == nums[r - 1]){
// r++;
// }
}
}
}
return ansList;
}
public static void main(String[] args) {
leetcode15 obj = new leetcode15();
for (List<Integer> list : obj.threeSum(new int[]{-1, 0, 1, 2, -1, -4})) {
for (int num : list){
System.out.print(num);
}
System.out.println();
}
}
}