回溯法

作者: 该用户已趴倒 | 来源:发表于2020-05-25 17:16 被阅读0次

回溯法是一种试探性的算法。它建立在递归的基础上,在不满足条件的情况下,立刻停止前进,返回之前的状态。

基本算法结构

def fn(n, solution):
    # 1. 判断输入是否非法
    if n < 0:
        return

    # 2. 判断递归是否要结束
    if n == len(solution):
        return True

    # 3. 遍历所有可能的情况
    for i in range(n):
        solution.append(i)
        # 递归
        fn(i, solution)
        # 4. 回退到上一步骤
        solution.pop()

例如N皇后问题

在一个 nxn 的国际棋盘上放置皇后,保证每行每列,每个斜对角方向只有一个皇后,求解所有可能的解法。

假设我们是一个 4x4 的棋盘,使用暴力解法先枚举出来 4⁴ 种可能的组合方式,然后依次判断每一种是否可用。这种算法的时间复杂度相当于 O(nⁿ)

先给出如何判定是否合法的函数:

# data 里面保存的是每一行有皇后的列索引
def valid(data):
    row = len(data) - 1
    r = data[row]
    for i in range(row):
        # 检测垂直和斜对角方向是否有其它棋子
        if data[i] == r or (abs(data[i] - r) == (row - i)):
            return False
    return True

使用回溯法解决这个问题的代码:

def backtracking(n, data, results):
    row_num = len(data)
    # 摆放完成的情况
    if row_num == n:
        results.append(data.copy())
        return
    for col in range(n):
        data.append(col)
        # 检查是否符合要求。满足的时候执行递归
        if valid(data):
            backtracking(n, data, results)
        # 恢复之前的状态继续尝试
        data.pop()


def nquene(n, results):
    data = []
    backtracking(n, data, results)

时间复杂度进行分析

观察 backtracking 函数,其中有一个长度为 n 的遍历,然后算法核心部分是递归和valid 判定
所以算法的整体负载度为:T(n) = n * (T(迭代) + T(valid))

  • valid 函数的时间复杂度是随 data 的长度而增长的,最大的情况下为 O(n)
  • 迭代部分每次将问题的规模缩小1

所以T(n) = n * (T(n - 1) + O(n)) = n * T(n - 1) + O(n²)
这个样式不满足公式法的模板,所以我们使用迭代法进行分析

T(n) = n*((n - 1) * T(n - 2) + O(n-1)^2) + O(n^2)
T(n) = (n * (n - 1) * (n - 2) ... * 1) + (1 + 2^2 + 3^2 + ... + n^2)

前面是 n 的阶乘,后面是n 的平方和。利用平方和公式可以得知
T(n) = n! + O(n * (n + 1) * (2n + 1) / 6)
化简得到: T(n) = n! + O(n^3)
因为阶乘的变化趋势要大于立方,所以最终时间复杂度为 T(n) = n!

相关文章

  • N皇后

    回溯法核心代码: n皇后问题回溯法

  • 简单的谈谈dfs

    简单的说回溯法,递归就是将函数负责几遍。那么回溯法就是将for循环复制几遍。回溯法框架 为什么要把list的最后一...

  • 算法08-回溯法:面试最常见问题

    算法08-回溯法:面试最常见问题 一、介绍 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜...

  • 回溯法与分支限界法

    回溯法与分支限界法 时间 2016-03-24 标签 搜索 回溯法 1、概念 回溯算法实际上一个类似枚举的搜索尝...

  • LeetCode之回溯算法

    回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。因为回溯的本质是穷举,穷...

  • 小朋友学经典算法(14):回溯法和八皇后问题

    一、回溯法 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步...

  • 算法的设计思想2

    4,回溯法 回溯法是一种优化的穷举法。所谓穷举法就是穷举问题的所有可能性,直到发现解决问题的最佳解为止。回溯法会有...

  • 算法理论 | 回溯法

    回溯法 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并...

  • 78. Subsets

    经典的回溯法

  • 491. Increasing Subsequences

    典型的回溯法

网友评论

      本文标题:回溯法

      本文链接:https://www.haomeiwen.com/subject/cpnyahtx.html