题目
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
可以先固定一个数字,剩下的两个数字只要相加等于这个固定数字的相反数,那么这三个数的和不就为零了。
k 是对应的每个固定的数,在这个基础上,i 指向k的下一个数,j指向数组的后一个数。用一个循环while(i != j)
让这两个指向逐渐靠拢,如果这两个数的和twoSum正好等于-k,不就说明找到这三个数了,加入到结果的集合里就行。如果这两个数的和twoSum > -k , 说明和大了,只用让两数的和变小就行,因为已经排序了,j所指向的那边大一些,即j–。反之,则i++。
还要记得去重,如果当前所固定的值(k),与上一个固定的值(k-1)相等(所以k要从第二个开始,即k>0),跳过就好了。即if(k > 0 && nums[k] == nums[k-1]) continue;
当移动的两个数相加等于-k时,同样记得去重,只要 i 的下一个数和 i 相等,就i++,移动到下一个值。对应的 j 是 j–。最后还要记得再把 i 加一次,j 减一次,这样才正好指向两个对应不相等的值。
排序后 可以提前判断一下,如果数组长度<3,或者排序后的第一个数就>0,或排序后最后一个数<0,就没必要再往下运行了。
java代码
List<List<Integer>> result = new ArrayList<List<Integer>>();
int len = nums.length;
int i = 0, j = 0, target = 0;
Arrays.sort(nums);
if(len < 3 || nums[0] > 0 || nums[len-1] < 0) return result;
for(int k = 0; k < len; k++) {
if(nums[k] > 0) break;
if(k > 0 && nums[k] == nums[k-1]) continue;
i = k + 1;
j = len - 1;
target = 0 - nums[k];
while(i < j) {
int twoSum = nums[i] + nums[j];
if(target == twoSum) {
result.add(Arrays.asList(nums[k],nums[i],nums[j]));
while(i < j && nums[i] == nums[i+1]) ++i;
while(i < j && nums[j] == nums[j-1]) --j;
++i;
--j;
}else if(twoSum > target) {
j--;
}else {
i++;
}
}
}
return result;
if(len < 3 || nums[0] > 0 || nums[len-1] < 0) return result;
Arrays.sort(nums);
刚是先判断。。。怪不得错呢