返回

剖析「前端刷题」第 63 题:动态规划算法巧解不同路径 II

前端

问题分析

「不同路径 II」问题如下:给定一个二维网格,每个格子可能是空(0)或者障碍(1)。求从左上角到右下角的不同路径数。注意,你只能向右或向下移动。

动态规划算法

动态规划算法是一种自顶向下的求解策略,适用于求解具有重叠子问题且子问题之间具有最优子结构的优化问题。对于「不同路径 II」问题,我们可以通过动态规划算法,将原问题分解为多个子问题,并逐步求解这些子问题。

具体来说,令 dp[i][j] 表示从左上角到 (i, j) 格子的不同路径数。那么,如果 grid[i][j] 为 0,即当前格子不为障碍物,则有:

dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

其中,dp[i - 1][j] 表示从左上角到 (i - 1, j) 格子的不同路径数,dp[i][j - 1] 表示从左上角到 (i, j - 1) 格子的不同路径数。

如果 grid[i][j] 为 1,则当前格子为障碍物,则 dp[i][j] 为 0。

代码实现

基于动态规划算法,我们可以写出「不同路径 II」问题的代码实现,如下所示:

def unique_paths_with_obstacles(grid):
    m, n = len(grid), len(grid[0])
    dp = [[0] * n for _ in range(m)]

    for i in range(m):
        for j in range(n):
            if grid[i][j] == 1:
                dp[i][j] = 0
            else:
                if i == 0 or j == 0:
                    dp[i][j] = 1
                else:
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

    return dp[m - 1][n - 1]

复杂度分析

该算法的时间复杂度为 O(mn),其中 m 和 n 分别是网格的行数和列数。空间复杂度为 O(mn),因为我们使用了一个二维数组 dp 来存储子问题的结果。

总结

通过剖析「前端刷题」第 63 题「不同路径 II」,我们深入理解了动态规划算法在求解路径问题中的强大威力。动态规划算法将原问题分解为多个子问题,逐步求解,最终得到全局最优解。掌握动态规划算法是解决这类问题的关键,它不仅在前端开发中,在机器学习、计算机视觉、自然语言处理等人工智能领域都有着广泛的应用。