• 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

  • 相关阅读:
    CHttpFile调试
    关于linux下网络编程socket 转换IP问题 inet_ntoa()
    vc使用SetTimer回调函数
    OpenGL+VC6.0开发环境搭建
    Java StringBuffer和StringBuilder类
    Java String类
    Java 异常处理
    hashcode()和equals()的作用、区别、联系
    抽象类可以继承实体类吗?
    Java 向上造型详解
  • 原文地址:https://www.cnblogs.com/lihaozy/p/2800118.html
Copyright © 2020-2023  润新知