📅  最后修改于: 2023-12-03 15:42:20.426000             🧑  作者: Mango
本题给定一个由 '0'
和 '1'
组成的矩阵,其中 '0'
表示一个门,'1'
表示墙壁。你的任务是求解从矩阵任意一扇门出发到达其他任意一扇门所需的最小步数。
def minimum_step_to_reach_the_other_door(n: int, m: int, arr: List[List[str]]) -> int:
pass
n
:表示矩阵的行数,约束范围为 $1 \leq n \leq 1000$。m
:表示矩阵的列数,约束范围为 $1 \leq m \leq 1000$。arr
:表示矩阵,一个由类型为 List
且长度为 m
的 List
组成的 List
,其中每个子 List
等长,且其元素为 '0'
或 '1'
。-1
。输入:
n = 5
m = 5
arr = [['0', '1', '1', '0', '0'],
['0', '0', '0', '1', '0'],
['1', '1', '0', '0', '1'],
['1', '1', '1', '1', '0'],
['1', '0', '0', '1', '0']]
输出:
9
从所有的门出发,通过广搜算法找到所有门之间的最短路径,最后取最小值即可。
from typing import List, Tuple, Dict, Any, Union
def minimum_step_to_reach_the_other_door(n: int, m: int, arr: List[List[str]]) -> int:
queue = []
visited = {}
ans = float('inf')
for i in range(n):
for j in range(m):
if arr[i][j] == '0':
queue.append((i, j, 0))
visited[(i, j)] = True
if len(queue) == 1:
return 0
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
while len(queue) != 0:
x, y, steps = queue.pop(0)
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m and (nx, ny) not in visited and arr[nx][ny] == '0':
queue.append((nx, ny, steps+1))
visited[(nx, ny)] = True
if len(visited) == len(queue)+1:
ans = min(ans, steps+1)
return ans if ans != float('inf') else -1
广搜算法的平均时间复杂度为 $O(V+E)$ ,其中 $V$ 为节点数(门的个数), $E$ 为边数(相邻门之间的距离总和),在本题中即为所有门之间的距离总和。
在最坏情况下,所有格子都是门,假设门数量为 $k$,则 $V=k$,$E=\frac{k(k-1)}{2}$,则广搜的时间复杂度为 $O(k^2)$。特别地,当 $k=1$ 时(即只有一扇门),其时间复杂度为 $O(1)$。
因此,本题的时间复杂度为 $O(k^2)$,其中 $k \leq nm$。
空间复杂度为 $O(k)$,其中 $k$ 为门的数量。