Finding all unique triplets that sums to zero[部分转载]

题目:

http://www.leetcode.com/2010/04/finding-all-unique-triplets-that-sums.html

 

分析:

首先brute force,O(n3)。i j k从0到n-1各循环一遍,肯定不能要。

其次,我们先假设只有2个数,对于一个排序的数组来说,如果想要a + b = 0,那么可以两个指针,一个在head(),一个在tail(),然后判断这两个it的值相加是否等于0,如果小于,那么前面的指针++,如果大于,那么后面的指针--,直到指针相遇或者找到和为0的一对。这使得2个数字的算法复杂度由O(n2) -> O(n)。

然后,对于3个数字的相加,先变为 a + b = -c; 那么,对于其中一个数,做一个O(n)的遍历,剩下两个数进行一个算法复杂度的降低(O(n2) -> O(n))。得到如下代码:

    set<vector<int> > threeSum(vector<int> &num) {
        sort(num.begin(), num.end());
        set< vector<int> > triplets;
        vector<int> triplet(3);
        int n = num.size();

        for (int i = 0; i < n; i++)
        {
            int j = i + 1;
            int k = n - 1;
            while (j < k)
            {
                if (num[j] + num[k] < 0 - num[i])
                    j++;
                else if (num[j] + num[k] > 0 - num[i])
                    k--;
                else
                {
                    vector<int>::iterator it = triplet.begin();
                    *it++ = num[i];
                    *it++ = num[j];
                    *it++ = num[k];
                    j++;
                    k--;
                    triplets.insert(triplet);
                }
            }
        }
        return triplets;
    }

最终的复杂度为O(n2)。

 

另外转载一篇从网上看来的,返回值是vector< vector<int> >的解法,非常好!在LeetCode Online Judge上不会超时:

http://www.cnblogs.com/codingmylife/archive/2012/08/30/2663796.html

它的思想是手动过滤重复。

// Dedup directly, 
// LeetCode Judge Large, 272 milli secs.
vector<vector<int> > three_sum(vector<int> &num) 
{
    vector<vector<int> > ret;
    
    if (num.size() == 0) return ret;
    
    sort(num.begin(), num.end());
    
    for (vector<int>::const_iterator it = num.begin();
        it != num.end();
        ++it)
    {
        // Dedup
        if (it != num.begin() && *it == *(it - 1))
        {
            continue;
        }
        
        // Dedup, front = it + 1
        vector<int>::const_iterator front = it + 1;
        vector<int>::const_iterator back = num.end() - 1;
        
        while (front < back)
        {
            const int sum = *it + *front + *back;
            
            if (sum > 0)
            {
                --back;
            }
            else if (sum < 0)
            {
                ++front;
            }
            // Dedup
            else if (front != it + 1 && *front == *(front - 1))
            {
                ++front;
            }
            // Dedup
            else if (back != num.end() - 1 && *back == *(back + 1))
            {
                --back;
            }
            else
            {
                vector<int> result;
                
                // Already sorted.
                result.push_back(*it);
                result.push_back(*front);
                result.push_back(*back);
                
                ret.push_back(result);
                
                ++front;
                --back;
            }
        }
    }
    
    return ret;
}

 

 

 

 

EOF

posted on 2012-12-03 18:17  kkmm  阅读(300)  评论(0编辑  收藏  举报