LeetCode 015 3Sum

题目描述:3Sum

Given an array S of n integers, are there elements abc 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, a ≤ b ≤ c)
  • 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)

分析:

参考链接:http://blog.csdn.net/zhouworld16/article/details/16917071

2Sum:http://www.cnblogs.com/510602159-Yano/p/4242664.html

求解3个数的和,需要O(n2);去重,需要O(n);

① 对数组进行排序;

② i从0到n-1,对num[i]求另外两个数,这里用p和q;

③ p指向i+1,q指向结尾。sum = num[i] + num[p]+ num[q];

④ 利用加逼定理求解,终止条件是p == q;

⑤ 顺带去重。

去重时:

① 如果i到了i+1,num[i] == num[i - 1],则求出的解肯定重复了;

② 如果p++,num[p] = num[p + 1],则求出的解肯定重复了。

代码如下:

class Solution {
public:

    void InsertSort(vector<int> &a, int n){  
        int temp;  
        for (int i = 1; i < n; ++i){  
            temp = a[i];  
            int j;  
            for (j = i; j > 0 && temp < a[j - 1]; --j)  {  
                a[j] = a[j - 1];  
            }  
            a[j] = temp;  
        }  
    }  
    
    vector<vector<int> > threeSum(vector<int> &num) {
        
        vector<vector<int>> result;
        
        //小于3个数,则返回
        if(num.size() < 3) 
            return result;
            
        //对原数组非递减(递增)排序 
        InsertSort(num, num.size());
        int sum = 0;
        
        for(int i = 0; i < num.size(); i++){
            
            //去重
            if(i != 0 && num[i] == num[i-1]) 
                continue;
            
            int p = i + 1, q = num.size() - 1;
            
            //收缩法寻找第2,第3个数
            while(p < q){
                sum = num[i] + num[p] + num[q];
                
                if(sum == 0){
                    vector<int> newRes;
                    newRes.push_back(num[i]);
                    newRes.push_back(num[p]);
                    newRes.push_back(num[q]);
                    InsertSort(newRes,newRes.size());
                    result.push_back(newRes);
                    
                    //寻找其他可能的2个数,顺带去重
                    while (++p < q && num[p-1] == num[p]);
                    while (--q > p && num[q+1] == num[q]);
                }
                
                //和太小,p向后移动
                else if(sum < 0) 
                    p++;
                
                //和过大,q向前移动
                else 
                    q--;
            }
        }
        
        return result;
        
    }
};
原文地址:https://www.cnblogs.com/510602159-Yano/p/4278859.html