216. 组合总和 III

216. 组合总和 III

题意

  • 找出所有相加之和为 nk 个数的组合组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

    说明:

    • 所有数字都是正整数。

    • 解集不能包含重复的组合。

    示例 1:

    输入: k = 3, n = 7
    输出: [[1,2,4]]

    示例 2:

    输入: k = 3, n = 9
    输出: [[1,2,6], [1,3,5], [2,3,4]]

解题思路

由于最终的结果要求是有序的,因此需要先将数组进行排序;

  1. 回溯:维持一个路径组合,并且不断的将target减去数组中的值,直到target值为0,则把路径组合加入到最终的结果中;

  2. 记忆化搜索:通过字典记录下每个和对应的组合,在target在不断减去数组中的值的时候,如果这个和已经出现过,那么直接返回该和对应的组合,由于新的组合是在前面的组合的基础上进行操作的,所以没有办法对前面的组合进行剪枝;

  3. 动态规划:应该也是和2类似的思想;

实现

之前以为回溯都需要有值返回?,下面为有返回值的和没有返回值的做法。

class Solution(object):
   def combinationSum3(self, k, target):
       """
      回溯
      :type candidates: List[int]
      :type target: int
      :rtype: List[List[int]]
      """
       res = []
       candidates = [i for i in range(1, 10)]
       nums_len = len(candidates)
       
       def helper(depth, index, target, path):
           # 边界条件为剩余关键字减到了0,表明path中的值的和已经满足条件
           if depth == k:
               if not target:
                   res.append(path)
               return
           
           for idx in range(index, nums_len):
               # 如果剩余关键字比当前数字还要小的话,后面就没有循环的必要了
               # 所以从idx后面的继续找;
               if candidates[idx] in path:
                   continue
               if target >= candidates[idx]:
                   helper(depth+1, idx+1, target - candidates[idx], path + [candidates[idx]])
               else:
                   break
       
       helper(0, 0, target, [])
       return res
     
def combinationSum3(self, k, target):
       """
      记忆化搜索
      :type candidates: List[int]
      :type target: int
      :rtype: List[List[int]]
      """
       # 记录每个和对应的组合
       memorize = {}
       candidates = [i for i in range(1, 10)]

       def helper(target):
           if target in memorize:
               return memorize[target]
           
           new_conbinations = []
           for num in candidates:
               if num > target:
                   break
               elif num == target:
                   new_conbinations.append([num])
               else:
                   old_conbinations = helper(target-num)
                   for conbination in old_conbinations:
                       if num > conbination[0] or num in conbination:
                           continue
                       # 由于不能够确保num是否是正确的,能够加入到结果数组中,并且数组是可变对象
                       # 因此不能够将num append 到数组中
                       # 加入到前面是因为可以保证顺序,这是因为循环是从小到大的顺序来找出对应的target
                       new_conbinations.append([num] + conbination)
           
           memorize[target] = new_conbinations
           return new_conbinations
       
       helper(target)
       return filter(lambda conbination: len(conbination) == k, memorize[target])

转载于:https://www.cnblogs.com/George1994/p/7453590.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值