zoukankan      html  css  js  c++  java
  • 57 三数之和

    原题网址:https://www.lintcode.com/problem/3sum/description

    描述

    给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。

    在三元组(a, b, c),要求a <= b <= c。

    结果不能包含重复的三元组。

    您在真实的面试中是否遇到过这个题?  

    样例

    如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:

    (-1, 0, 1)

    (-1, -1, 2)

     

    标签

     

    排序
    两根指针
    数组
     
    思路:
    不考虑时间复杂度、空间复杂度的话,三重循环暴力破解,唉,菜鸟第一想法。找到一组答案后判断下是否与result中已有组合重复,这个判重可以单独定义成一个函数。
     
    AC代码:
    class Solution {
    public:
        /**
         * @param numbers: Give an array numbers of n integer
         * @return: Find all unique triplets in the array which gives the sum of zero.
         */
        vector<vector<int>> threeSum(vector<int> &numbers) {
            // write your code here
            vector<vector<int>> result;
        int size=numbers.size();
        for (int i=0;i<size;i++)
        {
            for (int j=i+1;j<size;j++)
            {
                for (int k=j+1;k<size;k++)
                {
                    if (numbers[i]+numbers[j]+numbers[k]==0)
                    {
                        vector<int> temp;
                        temp.push_back(numbers[i]);
                        temp.push_back(numbers[j]);
                        temp.push_back(numbers[k]);
                        sort(temp.begin(),temp.end());
                        if (result.empty())
                        {
                            result.push_back(temp);
                        }
                        else
                        {
                            bool canInsert=true;
                            for (int ind=0;ind<(int)result.size();ind++)
                            {
                                if(same(temp,result[ind]))
                                {
                                    canInsert=false;
                                    break;
                                }
                            }
                            if (canInsert)
                            {
                                result.push_back(temp);
                            }
                        }
                    }
                }
            }
        }
        return result;
        }
        
        
        bool same(vector<int> num1,vector<int> num2)
    {
        for (int i=0;i<(int)num1.size();i++)
        {
            if (num1[i]!=num2[i])
            {
                return false;
            }
        }
        return true;
    }
    
    };

     

    最开始我也是顺着两数之和的思路,先固定一个索引,另外两个数用哈希表,但会造成重复问题,并且会漏检一些组合,比如有多种组合nums【j】+ nums【k】= target的情况,只能检测出一种。
    网上看了别人的答案后醍醐灌顶,膜拜大神。
    详细见上面链接,简单说来就是先排序,然后固定一个数i,再用两个指针一根从头(i+1)一根从尾(n-1)遍历余下的元素,如果三个数的和等于0,push到结果中。如果和大于0,尾指针前移(减小总体和)。反之如果和小于0,头指针后移(增大总体和)。
    这里尤其注意去除重复,因为数组已经排过序,只需要判断i,j,k三根指针是否与上一个指向元素相同就可以了。
    代码,Lintcode说我 Time Limit Exceeded,emmmm……暴力破解反而通过?费解
    class Solution {
    public:
        /**
         * @param numbers: Give an array numbers of n integer
         * @return: Find all unique triplets in the array which gives the sum of zero.
         */
        vector<vector<int>> threeSum(vector<int> &numbers) {
            // write your code here
            vector<vector<int>> result;
        int n=numbers.size();
        sort(numbers.begin(),numbers.end());
        for (int i=0;i<n;i++)
        {
            if (numbers[i]>0)
            {
                break;
            }
            if (i>0&&numbers[i]==numbers[i-1])//去除重复;
            {
                continue;
            }
            int j=i+1,k=n-1;
            while(j<k)
            {
                if (j>i+1&&numbers[j-1]==numbers[j])//去除重复;
                {
                    continue;
                }
                if (k<n-1&&numbers[k]==numbers[k+1])//去除重复;
                {
                    continue;
                }
                if (numbers[i]+numbers[j]+numbers[k]==0)
                {
                    vector<int> tmp(3,numbers[i]);
                    tmp[1]=numbers[j];
                    tmp[2]=numbers[k];
                    result.push_back(tmp);
                    j++;
                    k--;
                }
                else if (numbers[i]+numbers[j]+numbers[k]>0)
                {
                    k--;
                }
                else
                {
                    j++;
                }
            }
        }
        return result;
            
        }
    };

     

  • 相关阅读:
    springboot的build.gradle增加阿里仓库地址以及eclipse增加lombok
    mqttfx无法选择证书
    EMQX源码编译过程
    新环境chart包helmlint校验
    安装rebar3
    Ubuntu16.04下,erlang安装和rabbitmq安装步骤
    UTF-8,GBK,ANSI之间的关系和区别
    write命令
    bunzip2命令
    bzip2命令
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/9111270.html
Copyright © 2011-2022 走看看