算法记录 | Day11回溯算法
因为太忙了,所以一整个二叉树的一章都没做,之后慢慢补,今天先跟回溯。
回溯法,一般可以解决如下几种问题:
- 组合问题:N个数里面按一定规则找出k个数的集合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 棋盘问题:N皇后,解数独等等
LeetCode 77-组合
题目描述:给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。你可以按 任何顺序 返回答案。
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
解题思路
- 回溯算法
- 有点迷糊,有些懂,但不知如何写的。
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
res = []
path = []
def backtrack(n, k, startidx):
if len(path) == k:
res.append(path[:])
return
for i in range(startidx,n+1):
path.append(i)
backtrack(n,k,i+1)
path.pop()
backtrack(n,k,1)
return res
关于剪枝操作
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
res=[] #存放符合条件结果的集合
path=[] #用来存放符合条件结果
def backtrack(n,k,startIndex):
if len(path) == k:
res.append(path[:])
return
for i in range(startIndex,n-(k-len(path))+2): #优化的地方
path.append(i) #处理节点
backtrack(n,k,i+1) #递归
path.pop() #回溯,撤销处理的节点
backtrack(n,k,1)
return res
难点
- 有了模板之后,总是想着套模板,没有清楚地了解过程
- 剪枝操作可以怎么用
收获
- 回溯算法的模板。
- debug之后思路稍微清晰了一点,但还是主要靠背诵。