核心认知
回溯算法本质上是一种搜索。 它的典型过程是:- 做一个选择
- 进入下一层递归
- 撤销这个选择
- 尝试别的分支
哪类问题适合回溯
如果题目要求:- 求所有结果
- 求所有合法组合
- 求所有排列
- 列举全部路径
回溯模板里最重要的三个元素
写回溯时,你最好先明确这三件事:- 当前路径是什么
- 当前还能选什么
- 什么时候收集答案
为什么一定要撤销选择
因为你不是只走一条路径,而是要回到岔路口,继续探索别的分支。path.pop()。没有撤销,搜索树就走不干净。
回溯为什么总画成一棵树
因为它真的就是在树上搜索。 每往下一层,表示你多做了一个选择。每回退一步,表示你放弃当前分支,重新试别的可能。 所以做回溯题时,一个非常有效的方法是先在草稿纸上把搜索树大致画出来。
常见题型
回溯题常见有这些模型:- 组合
- 排列
- 子集
- 字符串切割
- 棋盘问题
- 去重搜索
剪枝为什么比模板更重要
回溯本质上是暴力搜索。真正让它变快的,往往不是模板,而是剪枝。 常见剪枝包括:
- 当前路径已经不合法,立即返回
- 当前和已经超过目标值,停止向下搜
- 同层去重,避免重复结果
学习建议
建议按这个顺序练:- 组合
- 子集
- 排列
- 组合总和
- 分割回文串
- N 皇后

