📅  最后修改于: 2023-12-03 15:10:05.870000             🧑  作者: Mango
给定一个 $m \times n$ 的矩阵,矩阵中每个元素都是 0 或 1,只能向右或向下移动一步。找到从左上角到右下角所需的最小步骤数。
例如,给定以下矩阵:
[
[0, 1, 0],
[0, 0, 1],
[1, 1, 0]
]
最小步骤数为 2。
我们可以使用动态规划来解决这个问题。定义 $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)$。
我们也可以使用广度优先搜索来解决这个问题。我们从左上角开始搜索,每次搜索可以向下或向右移动一步。如果到达右下角,我们返回搜索的步数。
为了避免重复搜索,我们需要记录每一个访问过的位置,防止死循环。
下面是 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 算法要慢一些,但是它能够处理那些无法写出状态转移方程的问题。