• LeetCode 39. 组合总和


    39. 组合总和

    Difficulty: 中等

    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的数字可以无限制重复被选取。

    说明:

    • 所有数字(包括 target)都是正整数。
    • 解集不能包含重复的组合。

    示例 1:

    输入:candidates = [2,3,6,7], target = 7,
    所求解集为:
    [
      [7],
      [2,2,3]
    ]
    

    示例 2:

    输入:candidates = [2,3,5], target = 8,
    所求解集为:
    [
      [2,2,2,2],
      [2,3,3],
      [3,5]
    ]
    

    提示:

    • 1 <= candidates.length <= 30
    • 1 <= candidates[i] <= 200
    • candidate 中的每个元素都是独一无二的。
    • 1 <= target <= 500

    Solution

    很基础的一道考察组合题目,一般排列组合类型的问题考察的就是回溯算法(组合总和IV那道题比较特殊,考察的是动态规划,使用回溯算法会超时)。有很多大佬总结过回溯算法经典解题框架(套路),简单来说就是:

    result = []
    def backtrack(路径, 选择列表):
        if 满足结束条件:
            result.add(路径)
            return
    
        for 选择 in 选择列表:
            做选择
            backtrack(路径, 选择列表)
            撤销选择
    

    用这个框架来解决问题的时候,需要注意两个问题:1. 递归什么时候结束?2. 元素是可以被重复使用的还是不可以被重复使用的?

    回到这个题目,题目给定了无重复元素的数组,并且数组内的元素可以被重复使用,只要保证从数组内选择的元素求的和等于target就行了。好,现在我们考虑上文提到需要考虑的两个问题:1. 数组内元素每次被使用之后,target减去该元素,直到target被减到0,说明找到了满足和为target的组合。2. 题目交代数组内的元素可以被重复使用,那么选择的列表就是candidates。回答了这两个问题,剩下的代码就好办了。

    解法一:

    class Solution:
        def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:       
            path = []
            res = []
            self.backtrack(candidates, path, target, res)
            return res
            
        def backtrack(self, nums, path, target, res):
            if target < 0:
                return
            if target == 0:
                res.append(path[:])
                return
            for i in range(len(nums)):
                path.append(nums[i])
                self.backtrack(nums, path, target-nums[i], res)
                path.pop()
    

    解法二:

    class Solution:
        def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
            res = []
            self.dfs(candidates, target, [], res)
            return res
            
        def dfs(self, nums, target, path, res):
            if target < 0:
                return
            if target == 0:
                res.append(path)
                return
            for i in range(len(nums)):
                self.dfs(nums[i:], target-nums[i], path+[nums[i]], res)
    
  • 相关阅读:
    怎样把Maven项目共享为传统Web项目
    伸冤人
    Maven依赖
    Maven常用插件参数
    Maven默认周期与插件
    MySQL Connector_J_5.1.34_2014.10
    MyEclipse2015对Javascript自动提示的终极支持
    Struts Convention Plugin 流程 (2.1.6+)
    Maven,预加载资源文件
    Myeclipse2014 自带的报表功能 与 Eclipse BIRT
  • 原文地址:https://www.cnblogs.com/swordspoet/p/14391418.html
Copyright © 2020-2023  润新知