给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// i < j < k
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
for(int i=0;i<n-2;i++){
int x = nums[i];
if(i>0 && x == nums[i-1])
continue; // 不能有重复的三元组,跳过重复数字
if (x + nums[i + 1] + nums[i + 2] > 0) break; // 优化一
if (x + nums[n - 2] + nums[n - 1] < 0) continue; // 优化二
int j = i+1;
int k = n-1;
while(j < k){ // 相向双指针
int sum = x + nums[j] + nums[k];
if(sum > 0)
--k;
else if(sum < 0)
++j;
else{
ans.add(List.of(x,nums[j],nums[k]));
for (++j; j < k && nums[j] == nums[j - 1]; ++j); // j跳过重复数字
for (--k; k > j && nums[k] == nums[k + 1]; --k); // k跳过重复数字
}
}
}
return ans;
}
}
有序数组 联想到 相向双指针
注意:
1、怎么跳过重复数字
2、优化一:如果最小的三个数加起来都大于0,那么直接结束就行了(结束整个循环)
3、优化二:如果当前nums[i]加上最大的两个数都小于0,那么可以结束此次循环