zoukankan      html  css  js  c++  java
  • leetcode 15 3Sum

    15. 3Sum
    题目描述
    Given an array nums of n integers, are there elements a, b, c in nums 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.

    Example:

    Given array nums = [-1, 0, 1, 2, -1, -4],

    A solution set is:
    [
    [-1, 0, 1],
    [-1, -1, 2]
    ]

    给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
    注意:
    1. 三元组(a、b、c、d)中的元素必须按非降序排列。(即a≤b≤c)
    2. 解集中不能包含重复的三元组。
        例如,给定的数组 S = {-1 0 1 2 -1 -4},↵↵    解集为:↵    (-1, 0, 1)↵    (-1, -1, 2)


    思路分析
    暴力解决法是每个人都能想到的,三层for循环,时间复杂度是O(n^3),而且还要处理重复的问题,显然不是题目想要的解法。

    那能不能降到O(n^2)?排序算法的时间复杂度为O(nlgn),小于O(n^2),那么我们不妨先对数组排个序。

    排序之后,我们就可以对数组用两个指针分别从前后两端向中间扫描了,如果是 2Sum,我们找到两个指针之和为target就OK了,那 3Sum 类似,我们可以先固定一个数,然后找另外两个数之和为第一个数的相反数就可以了。

    要我们找出三个数且和为0,那么除了三个数全是0的情况之外,肯定会有负数和正数,我们还是要先确定一个数,然后去找另外两个数,我们只要找到两个数且和为第一个确定数的相反数就行了。

    我们对原数组进行排序,然后开始遍历排序后的数组,这里注意不是遍历到最后一个停止,而是到倒数第三个就可以了。

    对于遍历到的数,用0减去这个确定的数得到一个target,然后只需要再之后找到两个数之和等于target即可。我们用两个指针分别指向fix数字之后开始的数组首尾两个数,如果两个数和正好为target,则将这两个数和fix的数一起存入结果中。然后就是跳过重复数字的步骤了,两个指针都需要检测重复数字。如果两数之和小于target,则我们将左边那个指针i右移一位,使得指向的数字增大一些。同理,如果两数之和大于target,则我们将右边那个指针j左移一位,使得指向的数字减小一些。
    由于不能有重复的三元组,因此若等于target后,需要对l和r都作重复判断。

    class Solution {
    public:
        vector<vector<int> > threeSum(vector<int> &num) {
            vector<vector<int>> res;
            sort(num.begin(),num.end());
            int n = num.size();
            for(int i=0;i<n;++i)
            {
                if(num[i]>0)
                    break;
                if(i>0&&num[i]==num[i-1])
                    continue;
                int t = 0-num[i];
                int l=i+1,r=n-1;
                while(l<r)
                {
                    if(num[l]+num[r]==t)
                    {
                        res.push_back({num[i],num[l],num[r]});
                        while(l<r&&num[l]==num[l+1]) l++;
                        while(l<r&&num[r]==num[r-1]) r--;
                        l++;r--;
                    }
                    else if(num[l]+num[r]<t)
                        l++;
                    else
                        r--;
                }
            }
            return res;
        }
    };
  • 相关阅读:
    java匿名对象
    Java面向对象详解
    Java语言基本语法
    Win7下JDK环境变量的设置
    LeetCode-Shortest Word Distance
    LeetCode-Count Complete Tree Nodes
    LeetCode-Palindrome Pairs
    LeetCode- Implement Trie (Prefix Tree)
    LeetCode-Lowest Common Ancestor of a Binary Tre
    LeetCode- Binary Tree Longest Consecutive Sequence
  • 原文地址:https://www.cnblogs.com/zl1991/p/12764018.html
Copyright © 2011-2022 走看看