1.题目

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

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

2.代码

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//集合里面再放集合
List<List<Integer>> result = new ArrayList<>();
//先将数组里的元素排序,由于最后返回的不是索引,因此可以排序,不然就不行
Arrays.sort(nums);
for(int i=0; i<nums.length; i++){
//假设第一个元素就是大于0的那么就没有再遍历的必要了,直接返回一个空的集合
if(nums[i]>0){
return result;
}
//这里是对i进行去重,保证有不重复的三元组注意是当前元素与前一个元素比较,而不是当前元素与后一个比较
if(i>0 && nums[i]==nums[i-1]){
continue;//如果是相同的话就跳过当前循环
}
//定义两个指针
int left = i+1;
int right = nums.length-1;
//循环的条件注意left不能等于right
while(right>left){
//判断是left移动还是right移动
int sum = nums[i]+nums[left]+nums[right];
if(sum>0){
right--;
}
else if(sum<0){
left++;
}else{
//此时是表示sum刚好为0,那么就要先把这三个数添加到数组再添加到集合中去
result.add(Arrays.asList(nums[i],nums[left],nums[right]));
//接着在添加之后,还得继续去重,此时是针对left和right的
while(right>left && nums[left]==nums[left+1]){
left++;
}
while(right>left && nums[right]==nums[right-1]){
right--;
}
//最后添加完后且去重后,还是要移动指针的
right--;
left++;
}
}
}
return result;
}
}

 总结的话,重点一个是先排序然后想到双指针(其实也算是三指针),然后还要重点考虑去重的问题,不仅是对i去重left和right也要去重,就是思路要清晰