CC's Boat

一顾青山舟远去,归来仍是顾青山

0%

代码随想录算法训练营第二十九天

今天主要回顾了一下回溯算法专题,该专题主要有:

  • 组合问题
  • 切割问题
  • 子集问题
  • 排列问题
  • 棋盘问题

这样几类,应该注意组合和排列的区别,以及子集问题和组合/排列问题的区别。 组合和排列的主要区别在于元素顺序是否对答案集有所影响上,比如对给定数组[1, 2]的组合为[1,2]但其排列却有[1,2], [2,1]两组。而子集问题和排列组合问题的区别则在于,排列组合问题通过递归和回溯收集整个递归树形结构的叶子节点,而子集问题则要收集沿途的所有节点。分割问题其实是组合问题的一种变体,但是要注意对字符串的操作以及递归的结束条件。

回溯的一般步骤有:

确定递归函数传入参数

确定递归终止条件

遍历处理单层节点,递归,回溯(撤销结果)

剪枝操作:

注意由于回溯法的暴力程度很高,所以在一般情况下能剪枝时应尽量剪枝,以降低搜索的时间开销。

几个值得讨论的点:

1.回溯撤销结果撤销的是本节点加入的结果,每个节点在完成自己的单层操作后都将自己从结果集中删除

2.树枝剪枝和树层剪枝的问题,在排列和组合问题中经常需要对结果进行去重,如果一个元素在同层已经使用过,那么对于相同的同层元素而言,没有继续遍历的需要