• 39组合总和


    题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
    说明:所有数字(包括 target)都是正整数。解集不能包含重复的组合。
    示例 1:
    输入: candidates = [2,3,6,7], target = 7,
          所求解集为:[[7],[2,2,3]]
    来源:https://leetcode-cn.com/problems/combination-sum/
    法一:自己的代码

    开始探索算法时,写的一个例子,算法中没有引入控制哪些数参与循环的参数.

    class Solution:
        def combinationSum(self, candidates, target: int):
            results = []
            l = len(candidates)
            def backtrack(a=[]):
                if sum(a) == target:
                    results.append(a)
                    return
                # 这样可以输出结果,但每次回溯的时候都会从2开始计算,导致结果有重复,
                # 事实上如果从3开始回溯的时候,下次只要继续从3开始就可以了,
                # 解决的办法是在回溯函数中新增加一个参数k,k中存储下次在数组a中要增加的数
                # 可见在回溯算法中,参数的传递非常重要
                if sum(a) + 2 <= 8:
                    backtrack(a + [2])
                if sum(a) + 3 <= 8:
                    backtrack(a + [3])
                if sum(a) + 5 <= 8:
                    backtrack(a + [5])
                # if sum(a) + 2 <= 8:
                #     backtrack(a + [2],[2,3,5])
                # if sum(a) + 3 <= 8:
                #     backtrack(a + [3],[3,5])
                # if sum(a) + 5 <= 8:
                #     backtrack(a + [5],[5])
                
                # 如果用下面的方法进行回溯,append()函数会改变数组a的值,不可用!!!
                # if sum(a) + 2 <= 8:
                #     a.append(2)
                #     backtrack(a)
                # if sum(a) + 3 <= 8:
                #     a.append(3)
                #     backtrack(a)
                # if sum(a) + 5 <= 8:
                #     a.append(5)
                #     backtrack(a)
                
            backtrack()
            print(results)
            # [[2, 2, 2, 2], [2, 3, 3], [3, 2, 3], [3, 3, 2], [3, 5], [5, 3]]
            return results
    if __name__ == "__main__":
        duixiang = Solution()
        a = duixiang.combinationSum([2,3,5],8)
    View Code

    改进后的代码:

    思路:利用for循环进行控制剪枝,关键是新加的参数控制了回溯函数的起点

    class Solution:
        def combinationSum(self, candidates, target: int):
            results = []
            candidates.sort()
            def backtrack(a=[], candidates=candidates):
                if sum(a) == target:
                    results.append(a)
                    return
                for j,i in enumerate(candidates):
                    if sum(a) + i <= target:
                        # 加入candidates[j:]控制回溯的起点,不加的话每次都是从头开始
                        # 注意这里的用[]的写法来传递数据,函数结束调用后,不改变candidates的值,这非常重要
                        backtrack(a + [i], candidates[j:])
                    # 如果某个数加上后已经大于目标值了,后面的数也就不用试了,直接中断循环
                    # 前提是要排序
                    else:
                        break
            backtrack()
            print(results)
            return results
    if __name__ == "__main__":
        duixiang = Solution()
        a = duixiang.combinationSum([1,2],4)
        print(a)
    View Code
  • 相关阅读:
    p(str or array) 传递数据以易于阅读的样式格式化后输出 bootstarp样式的打印函数
    [Err] 1067
    php 正则表达式
    Docker使用及dnmp构建
    记一次Ubuntu18.04升级到19.10的经历
    面试-Redis
    ubuntu截图软件deepin scrot
    docker 搭建 Hadoop
    Docker 遇到的坑
    RabbitMQ遇到的坑
  • 原文地址:https://www.cnblogs.com/xxswkl/p/11936177.html
Copyright © 2020-2023  润新知