zoukankan      html  css  js  c++  java
  • [LeetCode] 15. 3Sum 三数之和

    Given an array nums of n integers, are there elements abc 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]
    ]

    解法:排序 + 双指针。先对数组排序,然后遍历排序后的数组, 当循环到nums[i]时,对后面的数使用双指针left和right分别指向第一个和最后一个数,如果3个数的和等于0,就找到一组添加到结果中;如果小于0,说明和小了,要往大的方向移动,left指针右移1位;如果和大于0,说明大了,right指针左移1位。再看3个数的和。由于题目要求不能有重复的答案,所以对于每个指针移动后都要看是否和前面的相等,如果相等则跳过。

    Time: O(n^2)  Space: O(1)

    Java:

    public List<List<Integer>> threeSum(int[] num) {
        Arrays.sort(num);
        List<List<Integer>> res = new LinkedList<>(); 
        for (int i = 0; i < num.length-2; i++) {
            if (i == 0 || (i > 0 && num[i] != num[i-1])) {
                int lo = i+1, hi = num.length-1, sum = 0 - num[i];
                while (lo < hi) {
                    if (num[lo] + num[hi] == sum) {
                        res.add(Arrays.asList(num[i], num[lo], num[hi]));
                        while (lo < hi && num[lo] == num[lo+1]) lo++;
                        while (lo < hi && num[hi] == num[hi-1]) hi--;
                        lo++; hi--;
                    } else if (num[lo] + num[hi] < sum) lo++;
                    else hi--;
               }
            }
        }
        return res;
    }
    

    Python:

    def threeSum(self, nums):
        res = []
        nums.sort()
        for i in xrange(len(nums)-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l, r = i+1, len(nums)-1
            while l < r:
                s = nums[i] + nums[l] + nums[r]
                if s < 0:
                    l +=1 
                elif s > 0:
                    r -= 1
                else:
                    res.append((nums[i], nums[l], nums[r]))
                    while l < r and nums[l] == nums[l+1]:
                        l += 1
                    while l < r and nums[r] == nums[r-1]:
                        r -= 1
                    l += 1; r -= 1
        return res 

    Python:

    class Solution(object):
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            nums, result, i = sorted(nums), [], 0
            while i < len(nums) - 2:
                if i == 0 or nums[i] != nums[i - 1]:
                    j, k = i + 1, len(nums) - 1
                    while j < k:
                        if nums[i] + nums[j] + nums[k] < 0:
                            j += 1
                        elif nums[i] + nums[j] + nums[k] > 0:
                            k -= 1
                        else:
                            result.append([nums[i], nums[j], nums[k]])
                            j, k = j + 1, k - 1
                            while j < k and nums[j] == nums[j - 1]:
                                j += 1
                            while j < k and nums[k] == nums[k + 1]:
                                k -= 1
                i += 1
            return result  

    Python: wo

    class Solution(object):
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            res = []
            nums = sorted(nums)
            n = len(nums)
            i = 0
            while i < n - 2:
                j, k = i + 1, n - 1
                while j < k:                
                    s = nums[i] + nums[j] + nums[k]
                    if s > 0:
                        k -= 1
                    elif s < 0:
                        j += 1
                    else:
                        res.append([nums[i], nums[j], nums[k]])
                        j += 1
                        k -= 1
                        while nums[j-1] == nums[j] and j < k:
                            j += 1
                        while nums[k+1] == nums[k] and j < k :
                            k -= 1                                
                i += 1
                while nums[i-1] == nums[i] and i < n - 2:
                    i += 1
                
            return res  

    C++:

    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 (k > 0 && nums[k] == nums[k - 1]) continue;
                int target = 0 - nums[k];
                int i = k + 1, j = nums.size() - 1;
                while (i < j) {
                    if (nums[i] + nums[j] == target) {
                        res.push_back({nums[k], nums[i], nums[j]});
                        while (i < j && nums[i] == nums[i + 1]) ++i;
                        while (i < j && nums[j] == nums[j - 1]) --j;
                        ++i; --j;
                    } else if (nums[i] + nums[j] < target) ++i;
                    else --j;
                }
            }
            return res;
        }
    };
    

    类似题目:

    [LeetCode] 16. 3Sum Closest 最近三数之和

    [LeetCode] 259. 3Sum Smaller 三数之和较小值

    All LeetCode Questions List 题目汇总

      

  • 相关阅读:
    toodifficult 题解
    Code Chef February Challenge 2019题解
    LOJ#3085. 「GXOI / GZOI2019」特技飞行(KDtree+坐标系变换)
    LOJ#3084. 「GXOI / GZOI2019」宝牌一大堆(递推)
    LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)
    LOJ#6046. 「雅礼集训 2017 Day8」爷(分块)
    LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)
    LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)
    BZOJ4766: 文艺计算姬(Prufer序列)
    BZOJ3729: Gty的游戏(伪ETT)
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8495665.html
Copyright © 2011-2022 走看看