zoukankan      html  css  js  c++  java
  • 9-2

    39. 组合总和

    给定一个无重复元素的数组 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]
    ]

    Python most votes solution:

    class Solution(object):
        def combinationSum(self, candidates, target):
            """
            :type candidates: List[int]
            :type target: int
            :rtype: List[List[int]]
            """
            res = []
            candidates.sort()
            self.dfs(candidates, target, 0, [], res)
            return res
    
        def dfs(self, nums, target, start, path, res):
            if target == 0:
                res.append(path)
                return 
            for i in xrange(start, len(nums)):
                if target < nums[i]:
                    break
                self.dfs(nums, target-nums[i], i, path+[nums[i]], res)
    

    分析:

    (1)代码用到了树结构中的DFS(深度优先搜索)。

    (2)在代码最开始对candidates进行排序,是为了在递归中,一旦遇到不合适的情形,能够尽早地跳出循环,从而减少代码的运行时间。

    (3)如何构建这个递归结构?首先要明白每一次递归,target都要减去nums中的一个数,从而在整个递归调用中,每一次更新后的target控制了程序下一步的导向:

    • 如果target == 0,要return;
    • 如果target < nums[i],就没有再往深处搜索的必要了(因为nums是有序的,深度优先搜索的顺序是由小到大的),所以此时程序应尽早退出循环,往广度的方向进行搜索。

    (4)在每一轮递归中,要传递哪些参数?

    • 首先必须要有nums,因为我们在每一轮递归中都要用到nums中的数,而且在传递的过程中我们不能修改nums(因为程序要从最深的节点逐级返回);
    • 其次,必须要有target,它控制了程序下一步运行的方向。为了能够使target抵达递归基,同时代码采用的又是DFS策略,因此每次递归往深处进行时,target都要减去nums中的一个数(在满足条件的情况下是由最小的数减到最大的数,这一过程是由for循环实现的);
    • 再次,上一次递归的索引 i 也是要传递的,这可以避免不必要的搜索过程。例如,当程序已经搜索至 2 -> 3 时,利用索引 i 可以保证下一次搜索的数字是从3开始而不是从2开始的(因为在2 -> 3 -> 2之间,已经有过 2 -> 2 -> 3了,传递索引 i 可以避免这类重复搜索的情况);
    • 接着,要传递当前的搜索路径,在每次递归中,它也是动态变化的:每往下递归一层,它的路径中就增添一项;每往上回退一层,就回到先前的那个路径。传递该路径的目的是一旦找到符合题意的路径组合,就将它保存到res中。
    • 最后要传递res,它保存了所有满足要求的路径,用于最终函数结果的返回。
  • 相关阅读:
    loadrunner监控linux之linux下安装rpc
    Linux中top命令参数详解
    使用jmeter监控服务器性能指标
    jmeter连接mysql数据库配置
    loadrunner--设置代理录制
    页面下载时间细分图组成
    linux网络配置
    科学把妹法
    简单而强大的bitset
    名言札记
  • 原文地址:https://www.cnblogs.com/tbgatgb/p/11161972.html
Copyright © 2011-2022 走看看