Link: https://oj.leetcode.com/problems/3sum/
这题和2sum差不多,但“使用哈希表的解法并不是很方便,因为结果数组中元素可能重复,如果不排序对于重复的处理将会比较麻烦”//? Ref:http://blog.csdn.net/linhuanmars/article/details/19711651
Approach: 先排序,再左右夹逼。
Time: O(n^2+nlogn)=(n^2), Space: O(1)
但要注意:题目中说不允许出现duplicate triplets。有两种方法处理:
1 先用hashset存结果,再转到arraylist里
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
HashSet<ArrayList<Integer>> set = new HashSet<ArrayList<Integer>>();
Arrays.sort(num);
for(int i = 0; i < num.length; i++){
int j = i+1;
int k = num.length - 1;
while(j < k){
int sum = num[j] + num[k];
if(sum == -num[i]){
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(num[i]);
list.add(num[j]);
list.add(num[k]);
set.add(list);
j++;//there may be multiple triplets, so do not return here
k--;//there may be multiple triplets, so do not return here
}
else if ((sum < -num[i])){
j++;
}
else {
k--;
}
}
}
for(ArrayList<Integer> item : set){
result.add(item);
}
return result;
}
}
2 跳过值相等的元素 (见diff1)。比如数组里有两个3, 对第一个3遍历过以后,第二个3就不用处理了,因为所有和等于-3的都已经处理过了。
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
Arrays.sort(num);
for(int i = 0; i < num.length; i++){
if(i!=0 && num[i] == num[i-1]) continue;//diff1
int j = i+1;
int k = num.length - 1;
while(j < k){
int sum = num[j] + num[k];
if(sum == -num[i]){
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(num[i]);
list.add(num[j]);
list.add(num[k]);
result.add(list);//diff2
j++;
k--;
while(j < k && num[j] == num[j-1]){//diff3
j++;
}
while(j < k && num[k] == num[k+1]){//diff4
k--;
}
}
else if ((sum < -num[i])){
j++;
}
else {
k--;
}
}
}
return result;
}
}
Note: Both Approaches use this for loop to avoid duplicate triplets
for(int i = 0; i < num.length; i++){
int j = i+1;
int k = num.length - 1;
2015.1.31
Must have the the if and two whiles to avoid duplicates:
if(i!=0 && num[i] == num[i-1]) continue;//diff1
while(j < k && num[j] == num[j-1]){//diff3
j++;
}
while(j < k && num[k] == num[k+1]){//diff4
k--;
}
Input: | [-2,0,0,2,2] |
Output: | [[-2,0,2],[-2,0,2]] |
Expected: | [[-2,0,2]] |