Leetcode-3Sum

LiBlog發表於2014-11-28

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, abc)
  • The solution set must not contain duplicate triplets.
    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
Have you met this question in a real interview?
 
Analysis:
 
Solution:
 1 public class Solution {
 2     public List<List<Integer>> threeSum(int[] num) {
 3         List<List<Integer>> resList = new ArrayList<List<Integer>>();
 4         if (num.length<3) return resList;        
 5 
 6         Arrays.sort(num);
 7         Map<Integer,Integer> numMap = new HashMap<Integer,Integer>();
 8         for (int i=0;i<num.length;i++)
 9             if (numMap.containsKey(num[i]))
10                 numMap.put(num[i],numMap.get(num[i])+1);
11             else numMap.put(num[i],1);
12 
13         int first = 0;
14         int second = -1;
15         while (first<num.length-2){            
16             numMap.put(num[first],numMap.get(num[first])-1);
17             second = first+1;
18             while (second<num.length-1){
19                 numMap.put(num[second],numMap.get(num[second])-1);
20                 int left = 0-num[first]-num[second];
21                 if (left>=num[second] && numMap.containsKey(left) && numMap.get(left)>0){
22                     List<Integer> temp = new LinkedList<Integer>();
23                     temp.add(num[first]);
24                     temp.add(num[second]);
25                     temp.add(left);
26                     resList.add(temp);
27                 }
28                 numMap.put(num[second],numMap.get(num[second])+1);
29                 if (left<num[second]) break;
30                 while (second< num.length-1 && num[second]==num[second+1]) second++;
31                 second++;
32             }
33             numMap.put(num[first],numMap.get(num[first])+1);
34             while (first<num.length-2 && num[first]==num[first+1]) first++;
35             first++;
36 
37         }
38 
39         return resList;       
40     }
41 }

 NOTE: There is a way to solve this problem without using hashmap. Practice it!

Solution2: Two pointers.

The key point here is that:

if p1+p2+p3==0, then p2++ and p3--.

 1 public class Solution {
 2     public List<List<Integer>> threeSum(int[] num) {
 3        List<List<Integer>> res = new ArrayList<List<Integer>>();
 4        if (num.length<3) return res;
 5        Arrays.sort(num);
 6     
 7        
 8  
 9        //Find each solution.
10        int p1 = 0;
11        int p2,p3;
12        while (p1<num.length-2 && num[p1]<=0){
13            p2 = p1+1;
14            p3 = num.length-1;
15            while (p2<p3 && -num[p1]-num[p2]>=num[p2]){
16                int sum = num[p1]+num[p2]+num[p3];
17                if (sum==0){
18                    List<Integer> sol = new ArrayList<Integer>();
19                    sol.add(num[p1]);
20                    sol.add(num[p2]);
21                    sol.add(num[p3]);
22                    res.add(sol);
23                }
24 
25                if (sum<=0){
26                    p2++;
27                    while (p2<p3 && num[p2]==num[p2-1]) p2++;
28                } 
29 
30                if (sum>=0){
31                    p3--;
32                    while (p2<p3 && num[p3]==num[p3+1]) p3--;
33                }
34           }          
35           p1++;
36           while (p1<num.length-2 && num[p1]==num[p1-1]) p1++;
37        }
38 
39        return res;
40         
41     }
42 }