[leetcode]3Sum

此题是Two Sum的变种,Two Sum能从O(n^2)优化到O(n)。那么此题能从O(n^3)优化到O(n^2)。就是少了那一维n。

此处要注意:1.当有重复的数字时,要跳过;2.找好一个数字去寻找另外两个数字时,只需从右边部分寻找就行,否则会重复。

import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
        // Start typing your Java solution below
        // DO NOT write main() function
        Arrays.sort(num);
    	ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i < num.length; i++) {
        	if (i > 0 && num[i] == num[i-1]) continue;
        	int sum = 0 - num[i];
        	ArrayList<Pair> pairs = getSum(num, sum, i + 1);
        	for (int j = 0; j < pairs.size(); j++)
        	{
        		Pair pair = pairs.get(j);
        		ArrayList<Integer> arr = new ArrayList<Integer>();
            	arr.add(num[i]);
            	arr.add(pair.x);
            	arr.add(pair.y);
            	ans.add(arr);
        	}
        }
        return ans;
    }
    
    // sum is sorted
    private ArrayList<Pair> getSum(int[] num, int sum, int left) {
    	ArrayList<Pair> ans = new ArrayList<Pair>();
    	int right = num.length - 1;
    	while (left < right)
    	{
    		if (num[left] + num[right] == sum)
    		{
    			Pair p = new Pair();
    			p.x = num[left];
    			p.y = num[right];
    			ans.add(p);
    			while (left+1 < num.length && num[left] == num[left+1]) {
    				left++;
    			}
    			left++;
    			while (right - 1 >= 0 && num[right] == num[right - 1]) {
    				right--;
    			}
    			right--;
    		}
    		else if (num[left] + num[right] < sum)
    		{
    			left++;
    		}
    		else // (num[left] + num[right] > sum)
    		{
    			right--;
    		}
    	}
    	return ans;
    }
}

class Pair
{
	public int x;
	public int y;
}

第二次

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        vector<vector<int> > result;
        sort(num.begin(), num.end());
        int N = num.size();
        for (int i = 0; i < N; i++)
        {
            if (i != 0 && num[i] == num[i - 1])
                continue;
            int left = i + 1;
            int right = N - 1;
            while (left < right)
            {
                if (num[left] + num[right] == -num[i])
                {
                    vector<int> tmp;
                    tmp.push_back(num[i]);
                    tmp.push_back(num[left]);
                    tmp.push_back(num[right]);
                    result.push_back(tmp);
                    left++;
                    right--;
                    while (left < right && num[left] == num[left - 1]) left++;
                    while (left < right && num[right] == num[right + 1]) right--;

                }
                else if (num[left] + num[right] < -num[i])
                {
                    left++;
                    while (left < right && num[left] == num[left - 1]) left++;
                }
                else
                {
                    right--;
                    while (left < right && num[right] == num[right + 1]) right--;
                }
            }
        }
        return result;
    }
};

  

posted @ 2013-07-29 16:36  阿牧遥  阅读(220)  评论(0编辑  收藏  举报