leetcode 题解 || 3Sum 问题

来源:互联网 发布:网络电视直播软件不卡 编辑:程序博客网 时间:2024/05/16 07:32

problem:

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, 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)

找到三个和为0的数,按顺序输出,并且去掉重复的组合


thinking:

(1)直觉告诉我,先排序再搜索要更简单。

(2)双数求和可以采用二分查找(双指针),时间复杂度可以控制在O(nlogn),也可以推广到三数求和上!!!

但具体实现的时候,我走了弯路,导致时间复杂度最坏达到0(n*n)

先看看优秀的实现,确实很精细和简洁,细细品味:

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) {        // IMPORTANT: Please reset any member data you declared, as        // the same Solution instance will be reused for each test case.                vector<vector<int>> res;if (num.size() < 3)  //小于3个数return res;//对原数组非递减(递增)排序InsertSort(num,num.size());                 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;            int sum = 0;            //收缩法寻找第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());                    res.push_back(newRes);//寻找其他可能的2个数,顺带去重while (++p < q  && num[p-1] == num[p]){//do nothing}while (--q > p && num[q+1] == num[q]){//do noghing}                }                else if (sum < 0)  //和太小,p向后移动{                    ++p;}                else            //和过大,q向前移动{                    --q;}            }        }                return res;    }};
最后贴上我自己的版本,结果本地实测通过。

void find(int i, int &p, int j,vector<int> tmp, vector<vector<int> > &result){    cout<<"i "<<i<<"p "<<p<<"j"<<j<<endl;    cout<<tmp.at(i)<<"_"<<tmp.at(p)<<"_"<<tmp.at(j)<<endl;    int index=0xff;    while((index!=0x00)&&(p!=i)&&(p!=j))    {        if(tmp.at(i)+tmp.at(p)+tmp.at(j)>0)        {            p--;            index&=0x0f;        }        else if(tmp.at(i)+tmp.at(p)+tmp.at(j)<0)        {            p++;            index&=0xf0;        }        else if(tmp.at(i)+tmp.at(p)+tmp.at(j)==0)            {                vector<int> a;                a.push_back(tmp.at(i));                a.push_back(tmp.at(p));                a.push_back(tmp.at(j));                result.push_back(a);                cout<<"a.size() "<<a.size()<<endl;                return;            }    }//while}class Solution {public:    vector<vector<int> > threeSum(vector<int> &num) {        vector<vector<int> > result;        vector<vector<int> > result_1;        int i=0;        int j=num.size()-1;        int index1=0;        vector<int> tmp(num);        sort(tmp.begin(),tmp.end());        while((j-i>1)&&(index1<tmp.size()))        {            int p=(i+j)/2;            find(i,p,j,tmp,result);            if(tmp.at(i)+tmp.at(p)+tmp.at(j)<0)            {                i++;                index1++;            }            else            {               index1++;                j--;            }        }//while        unique_copy(result.begin(),result.end(),back_inserter(result_1));        return result_1;    }};



0 0
原创粉丝点击