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

说明有更快的解法!

浙公网安备 33010602011771号