Medium
刷狗家题库看到的类似的,这个题里面去duplicates的地方值得好好想一想。
为什么我们只在if (nums[i] + nums[left] + nums[right] == 0)
的情况下去重呢?因为如果nums[i] + nums[left] + nums[right] < 0
, 那么我们就算nums[left + 1] == nums[left]
, 仍然会得到nums[i] + nums[left] + nums[right] < 0
,所以left会一直++,不需要去重操作,nums[i] + nums[left] + nums[right] > 0
的情况也一样。然而在 (nums[i] + nums[left] + nums[right] == 0)
的时候,如果我们遇到nums[right - 1] == nums[right], 这时候我们可能就会取到重复的三个元素,比如[-2,0,0,2,2], 如果我们在第一次取到i = 0, left = 1, right = 4后,移动pointers到i = 0, left = 2, right = 3, 我们就拿到了duplicate,所以这里要检验一下如果有重复就继续left++或者right--.
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums == null || nums.length == 0){
return res;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 1; i++){
//去重第一个数字
if (i > 0 && nums[i] == nums[i - 1]){
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right){
if (nums[i] + nums[left] + nums[right] == 0){
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
while(left < right && nums[left] == nums[left + 1]) { // skip duplicates
left++;
}
while(left < right && nums[right] == nums[right - 1]) { // skip duplicates
right--;
}
left++;
right--;
} else if (nums[i] + nums[left] + nums[right] > 0){
right--;
} else {
left++;
}
}
}
return res;
}
}