• [LeetCode] 15 3Sum


    原题地址:

    https://leetcode.com/problems/3sum/description/

    题目:

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

    解法:

    这道题是2Sum的“进化版”,一开始我采用回溯法去解决,显然这是个极其不适合这道题目的方法,结果也如同猜测一样:TLE。这也给了我一个做这类题目的启发:当确定了结果中数组元素的个数时(特别是2个、3个这种),是肯定不会采用回溯法解决的。像Combination Sum那一类题目,结果中数组元素不确定时,才有可能使用回溯法。

    既然是2Sum的进化版,我们就可以采用类似的办法去解决。我们可以先确定一个元素,然后再遍历剩下的元素,只要剩下的元素中有两个元素的和是我们确定元素的相反数时,这三个元素就是其中一个结果了。2Sum的时间复杂度为O(n),我们再在外面加一层循环,时间复杂度为O(n2),可以接受。下面是代码:

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

    下面是代码中的一些细节:

    (1)首先要排序,然后最外的循环只需要循环到<=0的部分就可以了;

    (2)为了避免出现重复,要加入

    if (nums[k] == nums[k - 1] && k > 0) continue;

    这个语句,比如[-4, -1, -1, 0, 1, 2]这个样例,假如不加这个语句,会出现两个[-1,0,1].

    (3)下面这两个语句:

    while (i < j && nums[i + 1] == nums[i]) i++;
    while (i < j && nums[j - 1] == nums[j]) j--;

    想一下这个样例:[-2,0,0,2,2]

    假如不加这两个语句,结果会有两个[-2,0,2]:因为最外一层循环为-2时,i=1,j=4和i=2,j=3都符合条件,而两者会出现重复,因此要忽略等于前一个元素值的元素。

    总结一下(2)(3)这两点,可以发现这道题目会出现两种重复的原因,各自有不同的解决方法,这也是这道题困难的地方。

    相关题目:

    Two Sum:http://www.cnblogs.com/fengziwei/p/7501933.html

  • 相关阅读:
    商标查询网
    java: jsp:param中文乱码
    java:maven中webapp下的jsp不能访问web-inf下面的bean
    java:类集回顾
    java:类集操作,多对多的关系
    java:类集操作总结
    java:练习学校学生
    php发邮件:swiftmailer, php邮件库——swiftmailer
    java:练习超市卖场
    phalcon: 按年分表的model怎么建?table2017,table2018...相同名的分表模型怎么建
  • 原文地址:https://www.cnblogs.com/fengziwei/p/7827719.html
Copyright © 2020-2023  润新知