Sunday, August 16, 2015

015–3Sum

3Sum

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)

Hide Tags

Array Two Pointers

Hide Similar Problems

(M) Two Sum (M) 3Sum Closest (M) 4Sum

自己写了个哈希表的版本,但是为了去重,还得先排序。最终的性能不好,不知道是不是因为 map 操作费时?
双下标收拢是别人代码,回头自己再写一次。


class Solution {
public:
    //----------------------- two indexes shrinking ----------------------- 64 ms.
    vector<vector<int> > threeSum(vector<int>& nums) {
        vector<vector<int> > res;
        sort(nums.begin(), nums.end());
        int sz=nums.size();
        for (int i = 0; i < sz-2; ++i) {
            int left = i + 1, right = sz - 1, sum = 0 - nums[i];
            while (left < right)
            {
                if (nums[left] + nums[right] == sum)
                {
                    vector<int> out;
                    out.push_back(nums[i]);
                    out.push_back(nums[left]);
                    out.push_back(nums[right]);
                    res.push_back(out);
                    while (left < right && nums[left] == nums[left + 1])
                        ++left;
                    while (left < right && nums[right] == nums[right - 1])
                        --right;
                    ++left; --right;
                }
                else if (nums[left] + nums[right] < sum)
                    ++left;


                else
                    --right;
            }
            while(i<sz-2 && nums[i]==nums[i+1])
                i++;
        }
        return res;
    }
   
    //----------------------- use hash table ----------------------- 108 ms
    vector<vector<int>> threeSum_map(vector<int>& nums) {
        vector<vector<int>> rst;
        int sz=nums.size();


        sort(nums.begin(), nums.end());


        for(int ii=0; ii<sz-2; ++ii)
        {
            sumTwo(nums, ii, sz, rst);


            while(ii<sz-1 && nums[ii] == nums[ii+1])
                ii++;
        }
        return rst;
    }


    void sumTwo(vector<int> &numbers, int skipme, int sz, vector<vector<int>>& rst) {
        unordered_map<int, int> mm;
        int tgt = 0-numbers[skipme];
        for(int myIdx=skipme+2;myIdx<=sz;myIdx++)
        {
            int tmp = numbers[myIdx-1];
            if(mm.end()!=mm.find(tmp))
            {
                vector<int> buf(3, 0-tgt);
                buf[1]=mm[tmp], buf[2]=tmp;
                rst.push_back(buf);


                while(myIdx<=sz && numbers[myIdx-1] == numbers[myIdx])
                    myIdx++;
            }
            else
                mm[tgt-tmp] = tmp;
        }
    }   
};

No comments:

Post a Comment