1. 程式人生 > >【15】3Sum

【15】3Sum

先列舉中間的那個值(mid),然後O(N)尋找另外兩個值(left,right),使得left+right=-mid,即left+right+mid=0,總複雜度O(N^2)。唯一難點在於去掉重複。在確定mid之後,left和right都不能連續取兩個相同的值,即跳過重複區段,否則會出現重複。而mid可以與上一次相同,此時需要設定left為mid上一次的值,否則會出現重複。比如-1,0,0,0,1 mid可以取第二個0,這時left只能取第一個0,而不能取第一個0之前的數。如果一個數連續出現了3次以上,從第3次出現開始都不能取作mid

vector<vector<int>> threeSum(vector<int>& nums) {
    sort(nums.begin(),nums.end());
    int n=nums.size();
    vector< vector<int> > res;
    for(int m=1;m<n-1;m++){
        if(m>1 && nums[m]==nums[m-1] && nums[m-1]==nums[m-2])continue;
        int l=0,r=n-1;
        if(nums[m]==nums[m-1])l=m-1;
        while(l<m && r>m){
            int sum=nums[m]+nums[l]+nums[r];
            if(sum==0){
                vector<int> aRes(3);
                aRes[0]=nums[l];
                aRes[1]=nums[m];
                aRes[2]=nums[r];
                res.push_back(aRes);
                while(l+1<m && r-1>m && nums[l+1]==nums[l])l++;
                while(l+1<m && r-1>m && nums[r-1]==nums[r])r--;
                l++;
                r--;
            }
            else if(sum>0){
                while(l+1<m && r-1>m && nums[r-1]==nums[r])r--;
                r--;
            }
            else{
                while(l+1<m&& r-1>m && nums[l+1]==nums[l])l++;
                l++;
            }
        }
    }
    return res;
}