题目
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路
这道题看似很简单,其实挺难的。不过还是通用方法,不会就排序。先排序,思路就来了。
首先,我们要明确,3个数和为0,那么要么都是0,要么至少有一个负数。也就是说我们可以先找这个非正数。遍历到正数就结束。另外要注意要跳过重复。设遍历到的数为fix。
之后用0减去fix,得到剩下两个数的和target。
最后就是遍历fix之后的数组,查找和为target 的两个数,然后将这两个数和fix一起保存。依旧要注意跳过重复。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<List<Integer>>();
for(int i = 0; i<nums.length; i++){
//后面的数都大于0则不可能有和为0
if(nums[i] > 0) break;
//跳过相同元素
if(i > 0 && nums[i] == nums[i-1]) continue;
//
int fix = nums[i];
int target = 0 - fix;
for(int j = i+1,k = nums.length - 1;j<k ;){
if(target > nums[j] + nums[k]){
j++;
}else if(target < nums[j] + nums[k]){
k--;
}else{
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
res.add(list);
//跳过相同元素
while(j<k && nums[j] == nums[j + 1]){
j++;
}
j++;
//跳过相同元素
while(j<k && nums[k] == nums[k - 1]){
k--;
}
k--;
}
}
}
return res;
}
}
网友评论