[LeetCode] 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, 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)

解题思路:

1、网上有说不可以用hash表的方法计算,我想了一下,其实也是可以的,首先给元素排序,然后用map记录每个元素最大的下标。整个思想大致为,首先找到第一个元素,再找到第二个元素,然后利用hash表找到第三个元素。这道题一个难点是可能会有多个相同的结果,如何去重问题?注意到代码中若相同,则continue,这样便能去重了。

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        //题目转化为其中两个数是的和等于第三个数的相反数
        vector<vector<int>> result;
        int len = num.size();
        if(len<3){
            return result;
        }
        
        std::sort(num.begin(), num.end());
        map<int, int> numToMaxIndex;
        for(int i=len-1; i>=0; i--){
            if(i<len-1&&num[i]==num[i+1]){
                continue;
            }
            numToMaxIndex[num[i]]=i;
        }
        
        for(int i=0; i<len; i++){
            if(i>0&&num[i]==num[i-1]){
                continue;
            }
            for(int j=i+1; j<len; j++){
                if(j>i+1&&num[j]==num[j-1]){
                    continue;
                }
                int thirdNum = -(num[i]+num[j]);
                if(thirdNum<num[j]){ 
                    continue;
                }
                map<int, int>::iterator it=numToMaxIndex.find(thirdNum);
                if(it!=numToMaxIndex.end()&&it->second>j){
                    vector<int> triple({num[i], num[j], num[it->second]});
                    result.push_back(triple);
                }
            }
        }
        return result;
    }
};

2、另一种就是网上通用的两边夹的办法了。如下所示。

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        int n = num.size();
        sort(num.begin(), num.end());
        vector<vector<int> > res;
        for(int i = 0; i < n-2; i++)
        {
            if(i > 0 && num[i] == num[i-1])continue;//重复的元素不用计算
            int target2 = 0 - num[i];
            twoSum(num, i+1, target2, res);
        }
        return res;
    }
    void twoSum(vector<int> &sortedNum, int start, int target, vector<vector<int> >&res)
    {
        int head = start, tail = sortedNum.size() - 1;
        while(head < tail)
        {
            int tmp = sortedNum[head] + sortedNum[tail];
            if(tmp < target)
                head++;
            else if(tmp > target)
                tail--;
            else
            { 
                res.push_back(vector<int>{sortedNum[start-1], sortedNum[head], sortedNum[tail]});
                
                //为了防止出现重复的二元组,使结果等于target
                int k = head+1;
                while(k < tail && sortedNum[k] == sortedNum[head])k++;
                head = k;
                
                k = tail-1;
                while(k > head && sortedNum[k] == sortedNum[tail])k--;
                tail = k;
            }
        }
    }
};

二次刷题(2015-08-18)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        int len = nums.size();
        if(len < 3){
            return result;
        }
        std::sort(nums.begin(), nums.end());
        map<int, int> mapToIndex;   //值与最大下标的映射关系,防止取本身
        for(int i=0; i<len; i++){
            mapToIndex[nums[i]] = i;
        }
        for(int i=0; i<len; i++){
            if(i>0 && nums[i-1] == nums[i]){
                continue;
            }
            for(int j=i+1; j<len; j++){
                if(j>i+1 && nums[j-1]==nums[j]){
                    continue;
                }
                int num = - (nums[i] + nums[j]);
                map<int, int>::iterator it = mapToIndex.find(num);
                if(it != mapToIndex.end() && it->second > j){
                    result.push_back(vector<int>({nums[i], nums[j], it->first}));
                }
            }
        }
        return result;
    }
};


转载请注明:康瑞部落 » [LeetCode] 3Sum

0 条评论

    发表评论

    电子邮件地址不会被公开。 必填项已用 * 标注