# coding:utf-8
"""
Name : LeetCode18.py
Author : qlb
Contect : 17801044486@163.com
Time : 2021/2/6 21:30
Desc: 四数之和 扩展到 n数之和
"""
from typing import List
'''
对于三数之和,可以依次固定第一个数,然后解决两数之和的问题。那么,对于n数之和,也可以采用同样的思路,依次固定数据,
不断缩小问题的规模,最基本的情况还是两数之和问题,所以可以采用递归算法解决n数之和问题。
如果n==2,两数之和问题,正常求解;
如果n>2,则遍历固定第一个数,解决更小规模的n-1数之和的问题;
注意跳过数据重复的情况即可;
'''
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if len(nums) <= 3:
return []
nums.sort()
res = self.nSum(nums,4,target)
return res
def nSum(self,nums,n,target):
if len(nums) < n:
return []
# 放在 判断语句的外部
if n == 2:
res = []
left_idx = 0
right_idx = len(nums) - 1
while left_idx < right_idx:
if nums[left_idx] + nums[right_idx] == target:
res.append([nums[left_idx],nums[right_idx]])
while left_idx < right_idx and nums[left_idx + 1] == nums[left_idx]:
left_idx += 1
while left_idx < right_idx and nums[right_idx ] == nums[right_idx - 1]:
right_idx -= 1
left_idx += 1
right_idx -= 1
elif nums[left_idx] + nums[right_idx] > target:
right_idx -= 1
else:
left_idx += 1
return res
else:
res = []
for first_idx in range(len(nums)):
if first_idx > 0 and nums[first_idx] == nums[first_idx - 1]:
continue
subRes = self.nSum(nums[first_idx + 1:], n - 1, target - nums[first_idx])
for sub in subRes:
res.append([nums[first_idx]] + sub)
return res
test = Solution()
res = test.fourSum([1, 0, -1, 0, -2, 2],0)
print (res)