2.1.8 3Sum

来源:互联网 发布:spss因子载荷矩阵 编辑:程序博客网 时间:2024/06/02 20:14

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



0 0