LeetCode18四数之和扩展N数之和

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

 

posted @ 2021-02-06 22:34  qilibin  阅读(81)  评论(0编辑  收藏  举报