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);
            }
        }
    };
  • 相关阅读:
    vmware中三种网络连接方式
    【史上最全面经】各岗位汇总目录
    史上最全2019届秋招备战攻略
    程序员常用软件
    经典大数据面试题
    春招实习终于结束啦
    Java程序员自我介绍
    java一些面试题
    收割大厂offer需要具备的条件
    triangular distribution
  • 原文地址:https://www.cnblogs.com/wy1290939507/p/4536240.html
Copyright © 2011-2022 走看看