[Leetcode]4Sum

46 篇文章 0 订阅
4 篇文章 0 订阅

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • The solution set must not contain duplicate quadruplets.

    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)

求4个数的和为0的所有集合解~可以用和3Sum类似的解法来做,枚举第一二个数,然后用两个指针夹逼找到第三四个数,但这种解法复杂度为O(n^3)~还有一种O(n^2)复杂度的解法,先对num排序, 然后建一个dictionary, dict[num[i]+num[j]] = [(i,j) pairs 满足num[i] + num[j]], 而且这里的(i,j) pair总是满足i < j;然后用二层循环来搜, num[i]是四元组最小的数, num[j]是第二小的数, 判断dict中有没有target - (num[i] + num[j])这个key, 如果有, 就把找到的四个数加入最后的返回结果res~刚开始写的时候想在过程中直接处理重复元素,但老是不对,于是只能用set()去重~

class Solution:
    # @return a list of lists of length 4, [[val1,val2,val3,val4]]
    def fourSum(self, num, target):
        if num is None or len(num) < 4: return []
        num.sort()
        res, dict = set(), {}
        for i in xrange(len(num)):
            for j in xrange(i + 1, len(num)):
                if num[i] + num[j] not in dict:
                    dict[num[i] + num[j]] = [(i, j)]
                else:
                    dict[num[i] + num[j]].append((i, j))
        for i in xrange(len(num) - 3):
            for j in xrange(i + 1, len(num) - 2):
                remainder = target - (num[i] + num[j])
                if remainder in dict:
                    for pair in dict[remainder]:
                        if pair[0] > j:
                            res.add((num[i], num[j], num[pair[0]], num[pair[1]]))
        return [list(i) for i in res]
还有一种更简洁的写法,但思路是一样的~

class Solution:
    # @return a list of lists of length 4, [[val1,val2,val3,val4]]
    def fourSum(self, num, target):
        if num is None or len(num) < 4: return []
        num = sorted(num)
        result = set()
        cache  = collections.defaultdict(set)   
        for i in range(len(num)):
            for j in range(i + 1, len(num)):
                for half in cache[target - num[i] - num[j]]:
                    result.add(tuple(list(half) + [num[i], num[j]]))
            for j in range(i):
                cache[num[i] + num[j]].add((num[j], num[i]))
        return map(list, result)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值