思路:
不排序不好处理,所以先排序。
然后遍历数组(每个元素作为x),那么0-x则为2sum问题。
这个2sum双指针即可。显然结果集会有重复的,去重也是这个题的考点。
如何祛重呢?一开始我用的是set,代码如下(其实很慢的,但是我们还是AC了,笔试中简单方便):
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// Input: nums = [-4,-1,-1,0,1,2]
//Output: [[-1,-1,2],[-1,0,1]]
if(nums == null || nums.length<3) return new ArrayList<>();
Arrays.sort(nums);
Set<List<Integer>> resSet = new HashSet<>();
for(int x=0;x<nums.length-2;x++) {
int sum = 0-nums[x];
// begin 2sum
int i = x+1;
int j = nums.length-1;
while (i<j) {
int tempSum = nums[i]+nums[j];
if(tempSum > sum) {
j--;
}else if(tempSum < sum) {
i++;
}else if(tempSum == sum) {
List<Integer> tempList = new ArrayList<Integer>();
tempList.add(nums[x]);
tempList.add(nums[i]);
tempList.add(nums[j]);
resSet.add(tempList);
//trap 1
i++;
}
}
}
return new ArrayList<>(resSet);
}
}
下面正儿八经开始去重:(这里我看了答案)
首先因为排序了,所以第一重循环的x显然可以直接跳过。其次对每个x求解2sum的时候,也可以去重。代码如下:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// Input: nums = [-4,-1,-1,0,1,2]
//Output: [[-1,-1,2],[-1,0,1]]
if(nums == null || nums.length<3) return new ArrayList<>();
Arrays.sort(nums);
List<List<Integer>> resList = new ArrayList<>();
for(int x=0;x<nums.length-2;x++) {
if (x > 0 && nums[x] == nums[x - 1]) continue;
int sum = 0-nums[x];
// begin 2sum
int i = x+1;
int j = nums.length-1;
while (i<j) {
int tempSum = nums[i]+nums[j];
if(tempSum > sum) {
j--;
}else if(tempSum < sum) {
i++;
}else if(tempSum == sum) {
List<Integer> tempList = new ArrayList<Integer>(3);
tempList.add(nums[x]);
tempList.add(nums[i]);
tempList.add(nums[j]);
resList.add(tempList);
// 不能breakbreak,还有别的解
while(i<j && nums[i]==nums[++i]);
while(i<j && nums[j]==nums[--j]);
//i++;
//j--;
}
}
}
return resList;
}
}