Loading

Leetcode - 18. 四数之和

给你一个由n个整数组成的数组nums,和一个目标值target。请你找出并返回满足下述全部条件且不重复的四元组[nums[a], nums[b], nums[c], nums[d]]

  • 0 <= a, b, c, d < n
  • a、b、c 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target
    你可以按任意顺序返回答案 。

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

提示:

  • 1 <= nums.length <= 200
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解1 2021/8/29 O(n3)

from collections import defaultdict

def fourSum(nums: list, target: int) -> list:
    # 这题其实和3数之和没什么区别,只不过1)多了个数;2)之前的target=0
    # 简单情况处理
    len=nums.__len__()
    if len<=3: return []
    if len==4: return [] if sum(nums) != target else [nums]

    # 降规模
    # 排序后,存到字典,O(logn) + O(n)
    nums.sort()
    d=defaultdict(int)
    for x in nums:
        d[x]+=1
    # print(d)
    # O(n^3)遍历
    res=list()
    for x in d.keys():
        for y in d.keys():
            for z in d.keys():
                if y<x or z<y or (y==x and d[y]<=1) or (y==z and d[z]<=1) or (x==y==z and d[z]<=2): continue
                left=target-(x+y+z)
                # 避免答案的排列组合,[x,y,z,left]一定是递增的
                if left<z: continue
                if d.get(left):
                    if left==x or left==y or left==z:
                        ### 错误 - 1
                        ## x=y=z=left
                        #if left==x and d[x]>=4:
                        #    res.append([x, y, z, left])
                        ## x<y=z=left
                        #elif left==y and d[y]>=3:
                        #    res.append([x, y, z, left])
                        ## x<y<z=left
                        #elif d[z]>=2:
                        #    res.append([x, y, z, left])
                        ### 错误 - 1
                        # x=y=z=left
                        if left==x:
                            if d[x]>=4:
                                res.append([x, y, z, left])
                        # x<y=z=left
                        elif left==y:
                            if d[y]>=3:
                                res.append([x, y, z, left])
                        # x<y<z=left
                        elif left==z:
                            if d[z]>=2:
                                res.append([x, y, z, left])
                    # x<y<z<left
                    else:
                        res.append([x, y, z, left])
    return res

if __name__ == '__main__':
    print(fourSum([1,0,-1,0,-2,2],0))
    print(fourSum([2,2,2,2,2],8))
    print(fourSum([0,0,0,0],1))
    ### 错误
    # 1, [[0,0,3,4],[0,1,2,4],[0,2,2,3]]
    print(fourSum([2, 0, 3, 0, 1, 2, 4],7))

说明有更快的解法!

posted @ 2021-08-29 16:08  wwcg2235  阅读(51)  评论(0)    收藏  举报