public class Solution {
public List<List<Integer>> threeSum(int[] num) {
List<List<Integer>> results = new ArrayList<List<Integer>>();
if (num == null || num.length < 3) {
return results;
}
Arrays.sort(num);
int prev = 0;
for (int i = 0; i < num.length; i++) {
if (i > 0 && num[i] == prev) {
continue;
} else {
twoSumHelper(results, num, i);
prev = num[i];
}
}
return results;
}
private void twoSumHelper(List<List<Integer>> results, int[] num, int index) {
int firstNum = num[index];
int target = 0 - firstNum;
int start = index + 1;
int end = num.length - 1;
while (start < end) {
int secondNum = num[start];
int thirdNum = num[end];
int sum = secondNum + thirdNum;
if (sum == target) {
List<Integer> result = new ArrayList<Integer>();
result.add(firstNum);
result.add(secondNum);
result.add(thirdNum);
results.add(result);
int prevStart = num[start];
int prevEnd = num[end];
while (start < num.length && num[start] == prevStart) start++;
while (end > 0 && num[end] == prevEnd) end--;
} else if (sum < target) {
start++;
} else {
end--;
}
}
}
}
需要注意的是 41 和 42 行的:
while (start < num.length && num[start] == prevStart) start++;
while (end > 0 && num[end] == prevEnd) end--;
因为当 start 指针和 end 指针分别左移和右移的时候,需要跳过和之前一样的数字,否则:
Input: | [-2,0,0,2,2] |
Output: | [[-2,0,2],[-2,0,2]] |
Expected: | [[-2,0,2]] |
若只是单纯移动一步,则会造成重复的解出现,因为重复的没有跳过。