zoukankan      html  css  js  c++  java
  • 3 Sum

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
    Find all unique triplets in the array which gives the sum of zero.
    
    Example
    For example, given array S = {-1 0 1 2 -1 -4}, A solution set is:
    
    (-1, 0, 1)
    (-1, -1, 2)
    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.

    题解1 - 排序 + 哈希表 + 2 Sum

    相比之前的 2 Sum, 3 Sum 又多加了一个数,按照之前 2 Sum 的分解为『1 Sum + 1 Sum』的思路,我们同样可以将 3 Sum 分解为『1 Sum + 2 Sum』的问题,具体就是首先对原数组排序,排序后选出第一个元素,随后在剩下的元素中使用 2 Sum 的解法。

    C++:

    class Solution {
    public:
        vector<vector<int> > threeSum(vector<int> &num) 
        {
            vector<vector<int> > result;
            if (num.size() < 3) return result;
    
            int ans = 0;
    
            sort(num.begin(), num.end());
    
            for (int i = 0;i < num.size() - 2; ++i)
            {
                if (i > 0 && num[i] == num[i - 1])  
                    continue;
                int j = i + 1;
                int k = num.size() - 1;
    
                while (j < k)
                {
                    ans = num[i] + num[j] + num[k];
    
                    if (ans == 0)
                    {
                        result.push_back({num[i], num[j], num[k]});
                        ++j;
                        while (j < num.size() && num[j] == num[j - 1])
                            ++j;
                        --k;
                        while (k >= 0 && num[k] == num[k + 1])
                            --k;
                    }
                    else if (ans > 0) 
                        --k;
                    else 
                        ++j;
                }
            }
    
            return result;
        }
    };

    源码分析

    同python解法不同,没有使用hash map

    S = {-1 0 1 2 -1 -4}
    排序后:
    S = { -4  -1 -1 0 1 2}
          ↑  ↑        ↑
          i   j         k
              →        ←
    i每轮只走一步,j和k根据S[i]+S[j]+S[k]=ans和0的关系进行移动,且j只向后走(即S[j]只增大),k只向前走(即S[k]只减小)
    如果ans>0说明S[k]过大,k向前移;如果ans<0说明S[j]过小,j向后移;ans==0即为所求。
    至于如何取到所有解,看代码即可理解,不再赘述。
    

    复杂度分析

    外循环i走了n轮,每轮j和k一共走n-i步,所以时间复杂度为O(n2)。最终运行时间为52ms

  • 相关阅读:
    protobuf配置与使用
    gvim配置
    html div+css做页面布局
    php info
    开源相关工具汇总
    mem 0908
    linux dd指令
    java面试(2)--大数据相关
    Java基础面试题(1)
    转自ruby迷: 使用Net::SSH和Net::SCP编写Linux服务器管理脚本
  • 原文地址:https://www.cnblogs.com/lyc94620/p/10330181.html
Copyright © 2011-2022 走看看