递归&回溯
递归的基本性质:函数调用本身
把大规模的问题不断地变小,再进行推到的过程
回溯:利用递归的性质
从问题的起始点出发,不断尝试
返回一步甚至多步在做选择,直到抵达终点的过程
递归
递归算法是一种调用自身函数的算法
特点:可以使一个看似复杂的问题变得简洁和易于理解
经典案例:汉诺塔
汉诺塔python代码实现:
def hano(A: str, B: str, C: str, n: int) -> None:
if n > 0:
hano(A, C, B, n - 1)
print(A + "->" + C)
hano(B, A, C, n - 1)
if __name__ == '__main__':
hano('A', 'B', 'C', 5)
算法思想
- 要懂得如何将一个问题的规模变小
- 再利用从小规模问题中得出结果
- 结合当前的值挥着情况,得出最终的结果
通俗理解 - 把要实现的递归函数,看成已经实现好的
- 直接利用解决一些子问题
- 思考:如何根据子问题的解以及当前面对的情况得出答案
递归:自顶向下
动态规划:自底向上
递归写法结构总结 - 判断当前情况是否非法,如果非法就立即返回,也成为完整性检查(Sanity Check)
- 判断是否满足结束递归的条件
- 将问题的规模缩小,递归调用
- 利用在小规模问题中的答案,结合当前的数据进行整合,得出最终的答案
2种递归算法解决时间复杂度分析
迭代法
公式法
回溯
回溯算法是一种试探算法,与暴力搜索最大的区别:
在回溯算法种,是一步步向前试探,对每一步探测的情况评估,在决定是否继续,可避免走弯路
回溯算法的精华
- 出现非法的情况时,可退到之前的情景,可返回一步或多步
- 再去尝试别的路径和办法
想要采用回溯算法,就必须保证:每次都有多种尝试的可能
回溯算法解决问题的套路 - 首先判断当前情况是否非法,如果非常就立即返回
- 看看当前情况是否已经满足条件?如果是,就将当前结果保存起来并返回
- 在当前情况下,遍历所有可能出现的情况,并进行递归
- 递归完毕后,立即回溯,回溯的方法就是取消前一步进行的尝试