蜗牛慢慢爬 LeetCode 15. 3Sum [Difficulty: Medium]

题目

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

翻译

给定一个数组S,它包含n个整数,它是否存在3个元素a,b,c,满足a+b+c=0?找出所有满足条件的元素数组。
提示:a,b,c三个元素必须是升序排列(也就是满足a ≤ b ≤ c),最终的结果不能包含重复的元素数组。例如给定S为{-1 0 1 2 -1 -4},返回结果是(-1, 0, 1)和(-1, -1, 2)。

Hints

Related Topics: Array, Two Pointers
最容易想到的应该就是三重循环搞定 为了减少时间复杂度 自己原本是想到将最后一重循环用哈希表替换然后达到O(n^2)的效果 其中先排序可以减少很多麻烦

不过tag里面是有Two Pointers的 应该想到排序之后将二三重循环用两个指针夹逼 discuss中也是这么做的

代码

Java

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

Python

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        mymap = {}
        result = []
        for i in range(len(nums)):
            if nums[i] not in mymap:
                l = []
                l.append(i)
                mymap[nums[i]] = l
            else:
                mymap[nums[i]].append(i)
        for i in range(0, len(nums)-2):
            if nums[i]>0:
                break
            if i>0 and nums[i]==nums[i-1]:
                continue
            for j in range(i+1, len(nums)-1):
                if j>i+1 and nums[j]==nums[j-1]:
                    continue
                target = -nums[i]-nums[j]
                if target<nums[j]:
                    break
                mylist = []
                if target in mymap:
                    mylist = mymap[target]
                else:
                    continue
                for integer in mylist:
                    if integer!=i and integer!=j:
                        res = [nums[i],nums[j],nums[integer]]
                        result.append(res)
                        break
        return result

//better solution from discuss
class Solution(object):   
    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
        
原文地址:https://www.cnblogs.com/cookielbsc/p/7429769.html