class Solution(object):
def fourSum(self, nums, target):
lens = len(nums)
nums.sort()
res = set()
dicinum = {}
# 先求数字的两两之和,存到一个list里。
# 再两次for循环,将4sum转为2sum
# 2sum时,在list中找是否存在元素。
for i in range(lens-1):
for j in range(i+1,lens):
key = nums[i]+nums[j]
if key not in dicinum:
dicinum[key]= [(i,j)]
else:
dicinum[key].append((i,j))
# print(dicinum)
for i in range(lens-1): # for i in range(2,lens-1):
# 转为3数之和
for j in range(i+1,lens-2):
# 转为2数之和
diff2 = target - nums[i] - nums[j]
if diff2 in dicinum:
for index in dicinum[diff2]:
# print(index) #(4, 5) (2, 5)
if index[0]>j: # 不能重复取
res.add((nums[i], nums[j], nums[index[0]], nums[index[1]]))
print(res)
# {(-2, -1, 1, 2), (-2, 0, 0, 2), (-1, 0, 0, 1)}
return [list(i) for i in res]
# [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
# 超时
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums.sort()
res = set()
dicinum = {}
# 先求数字的两两之和,存到一个list里。
# 再两次for循环,将4sum转为2sum
# 2sum时,在list中找是否存在元素。
for i in range(len(nums)):
for j in range(i+1,len(nums)):
key = nums[i]+nums[j]
if key not in dicinum.keys():
dicinum[key]= [(i,j)]
else:
dicinum[key].append((i,j))
# print(dicinum)
for i in range(len(nums)):
# 转为3数之和
for j in range(i+1,len(nums)-2):
# 转为2数之和
diff2 = target - nums[i] - nums[j]
if diff2 in dicinum:
for index in dicinum[diff2]:
# print(index) #(4, 5) (2, 5)
if index[0]>j: # 不能重复取
res.add((nums[i], nums[j], nums[index[0]], nums[index[1]]))
print(res)
# {(-2, -1, 1, 2), (-2, 0, 0, 2), (-1, 0, 0, 1)}
return [list(i) for i in res]
# [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
N sum
把4数和分解为2数和的递归,并且上升到可以解决任意N数和
class Solution(object):
def fourSum(self, nums, target):
def findNsum(left, right, target, N, tmp_res, res):
if right - left + 1 < N or N < 2 or target < nums[left] * N or target > nums[
right] * N: # early termination
return
if N == 2: # 2数和
while left < right:
total = nums[left] + nums[right]
if total == target:
res.append(tmp_res + [nums[left], nums[right]])
left += 1
while left < right and nums[left] == nums[left - 1]:
left += 1
elif total < target:
left += 1
else:
right -= 1
else: # 递归
for i in range(left, right + 1):
if i == left or (i > left and nums[i - 1] != nums[i]):
findNsum(i + 1, right, target - nums[i], N - 1, tmp_res + [nums[i]], res)
nums.sort()
res = []
findNsum(0, len(nums) - 1, target, 4, [], res)
return res
参考: