# 回溯
解决一个回溯问题,实际上就是一个决策树的遍历过程。我们需要解决三个问题:
- 路径:也就是已经做出的选择。
- 选择列表:也就是当前可以做的选择。
- 结束条件:也就是到达决策树底层,无法再做选择的条件。
回溯算法的框架:
1 | result = [] |
其核心是for循环里面的递归,在递归调用之前[做选择],在递归调用之后[撤销选择]。
数独问题
大致的代码框架:
1 | void solveSudoku(char[][] board) { |
1 | // 从1到9做选择,全部试一遍 |
求子集问题
方法一,递归结构:
这个解法的时间复杂度很高,为O(N*2^N)。
1 | vector<vector<int>> subsets(vector<int>& nums) { |
方法二,回溯算法:
1 | vector<vector<int>> res; |
可以看到,对res的更新是一个前序遍历,也就是说,res是树上的所有节点。
组合问题
输入两个数字n, k,算法输出[1..n]中k个数字的所有组合。