zoukankan      html  css  js  c++  java
  • 3Sum 分类: Leetcode(线性表) 2015-02-04 10:51 51人阅读 评论(0) 收藏

    3Sum


    Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

    Note:

    • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
    • The solution set must not contain duplicate triplets.

        For example, given array S = {-1 0 1 2 -1 -4},
    
        A solution set is:
        (-1, 0, 1)
        (-1, -1, 2)


    暴力破解失败

    <span style="font-size:10px;">class Solution {
    public:
        vector<vector<int> > threeSum(vector<int> &num) {
            vector<vector<int>> result;
            if (num.size() <3) return result;
            vector<int> vec;
            sort(num.begin(), num.end());
            const int target = 0;
            
            int i,j,k;
            for(i = 0; i < num.size(); i++){
                for(j = num.size()-1; j > i; j--){
                    for(k = i; k < j; k++){
                        if(num[i]+num[k]+num[j] == 0){
                            vec.push_back(num[i]);
                            vec.push_back(num[k]);
                            vec.push_back(num[j]);
                            result.push_back(vec);
                        }
                    }
                }
            }
            return result;
        }
    };</span>


    下来考虑夹击,还需要注意题目的要求,不能三个数都相同
    class Solution {
    public:
        vector<vector<int> > threeSum(vector<int> &num) {
            vector<vector<int>> result;
            if (num.size() <3) return result;
            vector<int> vec;
            sort(num.begin(), num.end());
            const int target = 0;
            
            int i,j,k;
            int last = num.size();
            for(i = 0; i < num.size(); i++){
                j = i+1;
                if( i > 0 && num[i] == num[i-1]) continue;
                k = num.size()-1;
                while(j < k){
                    if( num[i] + num[j] + num[k] < target){
                        ++j;
                        while( num[j] == num[j-1] && j < k) ++j;
                    } else if( num[i] + num[j] + num[k] > target){
                        --k;
                        while( num[k] == num[k+1] && j<k) --k; 
                    } else{
                        result.push_back( {num[i],num[j], num[k]});
                        ++j;
                        --k;
                        while( num[j] == num[j-1] && num[k] == num[k+1] && j < k) ++j;
                    }
                }
            }
            return result;
        }
    };

    我们看到循环中j=i+1是在跳过相同数的前面的,这是因为两个数相同时可以的。i和k分别指向数组的起始和终止位置,循环中有i 和 j=i+1,然后i跳过所有相同的数,接下来考虑三个数的和,如果和小于目标函数,那么说明j取小了,我们移动j,如果和大于目标函数,说明k取大了,我们移动k.我们可以看到,其实只有二重循环,i的循环,对于每个i,在n-i的长度里移动j和k,所以这样时间复杂度就降为了O(n^2),时间复杂度降低的关键是算法一的k这层的循环在算法二中没有了。

     

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    spring
    C++容器常用方法简单总结
    【转】shell中各种括号的作用详解()、(())、[]、[[]]、{}
    c++创建对象时一些小细节
    ros建模与仿真(urdf介绍)
    常用vi命令
    Linux零零碎碎的小知识
    Linux目录都是些什么
    关于c/c++指针,指针的指针
    关于c/c++中的二维数组与指针
  • 原文地址:https://www.cnblogs.com/learnordie/p/4656957.html
Copyright © 2011-2022 走看看