LeetCode 39.组合总和

思路:

回溯的思路就是我们遍历每一个元素

这个元素选,或者不选

选那么下一次还可以选择这个元素或者不选这个元素 dfs(i, left - candidate[i])

不选这个元素就只能下一次只能选择下一个元素 dfs(i + 1, left)

我一直认为回溯学好的办法就是图画出来,清晰的知道为什么算法可以把每一种情况都跑出来,并且不会陷入死循环

Tip: csdn连图像都不能旋转我真是醉了

代码

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        ans = []
        path = []
        candidates.sort()

        def dfs(i, left):
            if left == 0:
                ans.append(path.copy())
                return
            if i == len(candidates) or left < candidates[i]:
                return 
            ## 不选
            dfs(i + 1, left)
            ## 选
            path.append(candidates[i])
            print(path)
            dfs(i, left - candidates[i])
            path.pop() 
        dfs(0, target)
        return ans

几个问题

 1、首先是为什么能够跑出答案:

 因为回溯直接把所有情况都枚举出来,知道撞到南墙我们才回去

 2、path 作为循环不变量, 他的含义一直是我们组合已经选择的数字

首先path 从图上直观的看就是我们从根节点,到某个节点的路径上的所有节点的列表

3、 path.pop() 到底是什么,回溯的恢复现场,到底是什么意思

path.pop()就是为了让path作为循环不变量,他的含义一直是我们组合已经选择的数字

从图上来看,path.pop() 执行的时候就是当沿着左孩子径我们走到方框时,我们需要切换到右孩子,这时候我们的左孩子就不在我们的路径上了,所以我们要pop()出来左孩子 

我是一个学习算法的初学者,希望把一切复杂的东西用最直观的方式解释出来,希望大家能指出我的不足,共同进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值