目录
今天终于开始学回溯了呜呜呜,还有半个月就要考CCF-CSP了,冲冲冲
理论基础
其实在讲解二叉树的时候,就给大家介绍过回溯,这次正式开启回溯算法,大家可以先看视频,对回溯算法有一个整体的了解。题目链接/文章讲解:代码随想录
77.组合
对着 在 回溯算法理论基础 给出的 代码模板,来做本题组合问题,大家就会发现 写回溯算法套路。在回溯算法解决实际问题的过程中,大家会有各种疑问,先看视频介绍,基本可以解决大家的疑惑。
本题关于剪枝操作是大家要理解的重点,因为后面很多回溯算法解决的题目,都是这个剪枝套路。
题目链接/文章讲解:代码随想录
思路
求组合的题目上次备考蓝桥杯时已经学过了,只能说我的知识迁移能力太弱了。。。(每日崩溃1/1)看Carl的链接可能更好理解。
代码
from typing import List
class Solution:
def combine(self,n:int,k:int)->List[List[int]]:
res=[] # 存放结果
self.backtracking(n,k,1,[],res)
return res
def backtracking(self,n,k,startIndex,path,res):
if len(path)==k:
res.append(path[:])
return
for i in range(startIndex,n-(k-len(path)+2)): #剪枝,确保得留下多少个给我遍历
path.append(i)
self.backtracking(n,k,i+1,path,res)
path.pop()
上面代码backtracking函数里的n-(k-len(path)+2)可能大家看不懂,我讲一下自己的理解,可以先看这张图:
图中要在1,2,3,4,,四个数里取4个数,当第一个取2时就不继续递归了,因为第一个数取2后面能取的数就剩3,4,怎么取都取不满4个数,就没必要继续递归了,进行剪枝。
n-(k-len(path)+2)就是这么个原理,总数减掉当前还需要的个数,+2是因为range()函数左闭右开的。(可以自己在纸上模拟一下,比如9个数取4个,最开始9-4=5,5+2=7,因为左闭右开,所以最高取到6,刚刚好6,7,8,9是能取到的最大的四位数了。)