zoukankan      html  css  js  c++  java
  • 【leetcode】3-sum(快排)

    一个数组,找出所有3个数加起来等于0的组合。不要重复的组合,并且按递增顺序输出结果。

    思路:先对数组进行一次快排。然后从最小的数开始,找到所有其后面的另外2个数与其和为0。3个数的和为0,确定了其中的一个,就是要找到另外的nums[m]+nums[n]=-nums[i]的数,由于一次循环中就已经找到了所有的m,n,因而相同的nums[i]就不必再考虑了。另外,对于求m,n的方法,其中一个确定,另一个就确定了,所以相同的nums[m]和nums[n]也不用再考虑。事实上nums[m]可以等于nums[n],但是对于确定的nums[i],nums[m]!=nums[m-1]。

    #include<iostream>
    #include<vector>
    using namespace std;
    
    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            vector<vector<int>> results;
            vector<int> triblets(3,0);
            nums.insert(nums.begin(),0);
            QSort(nums,1,nums.size()-1);
            for(int i=1;i<nums.size()-1;i++)
            {
                if(i>=2&&nums[i]==nums[i-1]) continue;    //下面的代码已经找到了和等于-nums[i]的所有数对,因而和前面相同的数就不用考虑了
                int m=i+1;                   
                int n=nums.size()-1;
                while(m<n)                             
                {
                    if(m>i+1&&nums[m]==nums[m-1]){                      //对于和确定的数,一个数确定了另一个数也就定了。所以nums[m]/nums[n]不变的值都不用考虑
                        m++;continue;
                    }
                    if(n<nums.size()-1&&nums[n]==nums[n+1]){
                        n--;continue;
                    }
                    if(nums[m]+nums[n]==-nums[i])
                    {
                        triblets[0]=nums[i];
                        triblets[1]=nums[m];
                        triblets[2]=nums[n];
                        results.push_back(triblets);
                        m++;n--;
                    }
                    else if(nums[m]+nums[n]>-nums[i])
                    {
                        n--;
                    }
                    else
                    {
                        m++;
                    }
                }
            }
            return results;
        }
    private:
        int Partition(vector<int>& L,int low,int high)   
        {
            L[0]=L[low];    //L[0]号位置是没有用的,用来存储枢纽值
            while(low<high)
            {
                while(low<high&&L[high]>=L[0]) --high;    //比哨兵位置大的值就不变,把high往前移
                L[low]=L[high];     
                while(low<high&&L[low]<=L[0]) ++low;     //比哨兵大的值才往后面移动,保证了所有小于等于哨兵的值都在哨兵的前面。
                L[high]=L[low];
            }
            //到此为止,low一定是等于high的
            L[low]=L[0];   //再把L[0]处的值还原到L[low]
            return low;
        }
        void QSort(vector<int>& L,int low,int high)
        {
            if(low<high)
            {
                int pivotloc=Partition(L,low,high);
                QSort(L,low,pivotloc-1);
                QSort(L,pivotloc+1,high);
            }
        }
    };
  • 相关阅读:
    URAL——DFS找规律——Nudnik Photographer
    URAL1353——DP——Milliard Vasya's Function
    URAL1203——DPor贪心——Scientific Conference
    递推DP HDOJ 5389 Zero Escape
    区间DP UVA 1351 String Compression
    树形DP UVA 1292 Strategic game
    Manacher HDOJ 5371 Hotaru's problem
    同余模定理 HDOJ 5373 The shortest problem
    递推DP HDOJ 5375 Gray code
    最大子序列和 HDOJ 1003 Max Sum
  • 原文地址:https://www.cnblogs.com/wy1290939507/p/4536240.html
Copyright © 2011-2022 走看看