码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode] 3Sum

时间:2015-04-19 16:13:49      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:c++   leetcode   

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)

解题思路:

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;
            }
        }
    }
};


[LeetCode] 3Sum

标签:c++   leetcode   

原文地址:http://blog.csdn.net/kangrydotnet/article/details/45128945

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!