基础
回溯是递归的副产品,只要有递归就会有回溯。
回溯法,一般可以解决如下几种问题:
- 组合问题:N个数里面按一定规则找出k个数的集合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 棋盘问题:N皇后,解数独等等
回溯法解决的问题都可以抽象为树形结构
回溯法的模版
func backtracking(参数) {
if (终止条件) {
存放结果
return;
}
for (横向遍历本层集合) {
处理节点
backtracking()
回溯
}
}
刷题
- 组合
回溯三部曲:
- 递归函数的参数和返回值
- 确定终止条件
- 确定单层的递归逻辑
嵌套for循环是不可取的,当key的值增加到n,就需要n层for循环来取值,无法通过代码来表达,这里需要使用递归和for循环来处理,把这道题转换为树状图来表示:
优化代码:在递归函数中直接记录,这一层需要遍历的start 和 end,节省内存
- 组合总和III
注意:在终止条件如果对path有修改,也需要进行回溯
- 电话号码的字母组合
总结
copy函数,将切片拷贝到一个新的副本
copy(sliceCopy, slice)