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]] |