zoukankan      html  css  js  c++  java
  • 【leetcode】3 SUM

    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.

    Note: 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]
    ]
    

    题意

    找到数组中三个数加起来的值等于0的所有集合。

    思路:

    2 SUM问题的解决方法是先将数组排序,前后分别一个指针向中间逼近,时间复杂度为O(NlogN)。所以3 SUM的做法可以模仿该做法,从数组中先取一个数t,再去用2 SUM的做法去获得剩下两个加和为-t的数。

    有一个最大的问题是结果去重,可以有两个方法解决,首先想到的是用set数据结构,另一种方法是遇到结果相同的数直接跳过。

    代码

    使用set的方法

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            sort(nums.begin(), nums.end());
            set<vector<int>> s;
            for(int i = 0;i<nums.size();i++)
            {
    			//如果第一个数已经大于0,可以不判断后面的数了,因为三个大于0的数不可能加起来等于0
                if(nums[i] > 0) break;
                vector<int> ans0(3,0);
                ans0[0] = nums[i];
                int t = 0 - nums[i];
                int l = i+1, r = nums.size()-1;
                while(l < r)
                {
                    if(nums[l] + nums[r] == t)
                    {
                        ans0[1] = nums[l];
                        ans0[2] = nums[r];
    					//如果下一个数等于前一个数,跳过该数
                        while(l<r && nums[l+1] + nums[r] == t) l++;
                        while(l<r && nums[l] + nums[r+1] == t) r++;
                        s.insert(ans0);
                        l++;
                        r--;
                    }else if(nums[l] + nums[r] < t)
                        l++;
                    else
                        r--;
                }
            }
    		//用set构造vector
            vector<vector<int>> ans(s.begin(), s.end());
            return ans;
        }
    };
    

    不使用set:

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            sort(nums.begin(), nums.end());
            vector<vector<int>> ans;
            for(int i = 0;i<nums.size();i++)
            {
                if(nums[i] > 0) break;
    			//如果下一个数和当前数相等,跳过
                if(i>0 && nums[i]==nums[i-1]) continue;
                vector<int> ans0(3,0);
                ans0[0] = nums[i];
                int t = 0 - nums[i];
                int l = i+1, r = nums.size()-1;
                while(l < r)
                {
                    if(nums[l] + nums[r] == t)
                    {
                        ans0[1] = nums[l];
                        ans0[2] = nums[r];
    					//如果下一个数和当前数相等,跳过
                        while(l<r && nums[l+1] + nums[r] == t) l++;
                        while(l<r && nums[l] + nums[r+1] == t) r++;
                        ans.push_back(ans0);
                        l++;
                        r--;
                    }else if(nums[l] + nums[r] < t)
                        l++;
                    else
                        r--;
                }
            }
            vector<vector<int>> ans(s.begin(), s.end());
            return ans;
        }
    };
    

    结果

    不使用set的做法速度更快一些。

    311 / 311 test cases passed.
    Status: Accepted
    Runtime: 49 ms

    311 / 311 test cases passed.
    Status: Accepted
    Runtime: 109 ms

  • 相关阅读:
    华为机试测试- 最小公倍数
    华为机试测试- 字符串最长的数字串
    华为机试测试- 大数相加
    Java 字符串倒序
    java BigDecimal
    华为机试测试-验证尼科彻斯定理
    华为机试测试-矩阵乘法-循环
    JAVA使用脚本引擎执行JS
    javascript学习之位置获取
    javascript学习笔记之DOM
  • 原文地址:https://www.cnblogs.com/puyangsky/p/6244018.html
Copyright © 2011-2022 走看看