📌  相关文章
📜  找到到达矩阵末尾所需的最小步骤 | 2套(1)

📅  最后修改于: 2023-12-03 15:10:05.870000             🧑  作者: Mango

找到到达矩阵末尾所需的最小步骤 | 2套

问题描述

给定一个 $m \times n$ 的矩阵,矩阵中每个元素都是 0 或 1,只能向右或向下移动一步。找到从左上角到右下角所需的最小步骤数。

示例

例如,给定以下矩阵:

[
  [0, 1, 0],
  [0, 0, 1],
  [1, 1, 0]
]

最小步骤数为 2。

解决方案1:动态规划

我们可以使用动态规划来解决这个问题。定义 $dp[i][j]$ 表示从 $(0,0)$ 到 $(i,j)$ 的最小步骤数。

如果 $matrix[i][j] = 1$,那么 $dp[i][j] = \infty$,表示这个位置不能到达。

否则,我们可以从上方或左侧到达 $(i,j)$,选择其中最小的一个路径即可:

$$ dp[i][j] = \min(dp[i-1][j], dp[i][j-1]) + 1 $$

最终的答案就是 $dp[m-1][n-1]$。

下面是 Python 代码:

def minSteps(matrix):
    m, n = len(matrix), len(matrix[0])
    dp = [[float('inf')] * n for _ in range(m)]
    dp[0][0] = 0
    for i in range(m):
        for j in range(n):
            if matrix[i][j] == 1:
                continue
            if i > 0:
                dp[i][j] = min(dp[i][j], dp[i-1][j] + 1)
            if j > 0:
                dp[i][j] = min(dp[i][j], dp[i][j-1] + 1)
    return dp[m-1][n-1]

这个算法的时间复杂度是 $O(mn)$,空间复杂度也是 $O(mn)$。

解决方案2:BFS

我们也可以使用广度优先搜索来解决这个问题。我们从左上角开始搜索,每次搜索可以向下或向右移动一步。如果到达右下角,我们返回搜索的步数。

为了避免重复搜索,我们需要记录每一个访问过的位置,防止死循环。

下面是 Python 代码:

def minSteps(matrix):
    m, n = len(matrix), len(matrix[0])
    queue = [(0, 0, 0)]
    visited = {(0, 0)}
    while queue:
        i, j, steps = queue.pop(0)
        if i == m-1 and j == n-1:
            return steps
        for di, dj in [(1, 0), (0, 1)]:
            ni, nj = i+di, j+dj
            if 0 <= ni < m and 0 <= nj < n and matrix[ni][nj] == 0 and (ni, nj) not in visited:
                queue.append((ni, nj, steps+1))
                visited.add((ni, nj))
    return -1

这个算法的时间复杂度是 $O(mn)$,空间复杂度也是 $O(mn)$。和动态规划算法相比,BFS 算法要慢一些,但是它能够处理那些无法写出状态转移方程的问题。