给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
提示:
3 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5
解:数组排序,然后分为三个指针min、mid、max,分别指向小中大的值,用min遍历数组,在(min + 1, max)进行筛选,mid左边界,max右边界,和值为sum,sum > 0移动右指针,sum < 0移动左指针,sum = 0记录并同时移动左右指针。注意:保证不重复可以在移动指针的同时观察和之前值是否相等(重复了)。比如遍历min指针时,观察nums[min - 1] = nums[min]是否相等,相等就跳过。
思路:Krahets
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int minIndex, midIndex, maxIndex; // 小,中,大指针
List<List<Integer>> ans = new ArrayList<>();
for (minIndex = 0; minIndex < nums.length; minIndex++) {
if (nums[minIndex] > 0) break;
if (minIndex > 0 && nums[minIndex] == nums[minIndex - 1]) continue;
midIndex = minIndex + 1;
maxIndex = nums.length - 1;
while (midIndex < maxIndex) {
int sum = nums[minIndex] + nums[midIndex] + nums[maxIndex];
if (sum > 0) {
while (midIndex < maxIndex && nums[maxIndex] == nums[--maxIndex]);
} else if (sum < 0) {
while (midIndex < maxIndex && nums[midIndex] == nums[++midIndex]);
} else {
List<Integer> list = new ArrayList<>();
Collections.addAll(list, nums[minIndex], nums[midIndex], nums[maxIndex]);
ans.add(list);
while (midIndex < maxIndex && nums[maxIndex] == nums[--maxIndex]);
while (midIndex < maxIndex && nums[midIndex] == nums[++midIndex]);
}
}
}
return ans;
}
}