回溯算法专题
| 2024-3-19
0  |  阅读时长 0 分钟
回溯法,一般可以解决如下几种问题:
  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等
 
回溯法抽象为树形结构后,其遍历过程就是:for循环横向遍历,递归纵向遍历,回溯不断调整结果集
子集问题分析:
  • 时间复杂度:,因为每一个元素的状态无外乎取与不取,所以时间复杂度为,构造每一组子集都需要填进数组,又需要,最终时间复杂度:
  • 空间复杂度:,递归深度为n,所以系统栈所用空间为,每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为
排列问题分析:
  • 时间复杂度:,这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。每个叶子节点都会有一个构造全排列填进数组的操作(对应的代码:result.push_back(path)),该操作的复杂度为。所以,最终时间复杂度为:n * n!,简化为
  • 空间复杂度:,和子集问题同理。
组合问题分析:
  • 时间复杂度:,组合问题其实就是一种子集的问题,所以组合问题最坏的情况,也不会超过子集问题的时间复杂度。
  • 空间复杂度:,和子集问题同理。
一般说道回溯算法的复杂度,都说是指数级别的时间复杂度,这也算是一个概括吧!
 
notion image
Loading...
目录