小S在一个𝑛×𝑚的网格迷宫中,初始位置在左上角 (1,1),目标是到达右下角 (n,m)。每个格子可以是黑色(表示为1)或者白色(表示为0)。他希望在移动过程中经过的黑色格子尽可能少。移动时可以向上、下、左、右四个方向移动,但不能走出迷宫的边界。请你帮小S计算从起点到终点所需经过的最少黑色格子的数量。
为了解决这个问题,我们可以使用广度优先搜索(BFS)算法。BFS 是一种非常适合寻找最短路径的算法,因为它会逐层扩展搜索,确保找到的路径是最短的。
解题思路: 理解问题:我们需要从网格的左上角 (0, 0) 移动到右下角 (n-1, m-1),并且希望经过的黑色格子(值为1的格子)尽可能少。
数据结构选择: 使用队列来实现 BFS。 使用一个二维数组 visited 来记录每个格子是否已经被访问过。 使用一个二维数组 black_count 来记录到达每个格子时经过的最少黑色格子数量。
算法步骤: 初始化队列,将起点 (0, 0) 加入队列,并记录初始状态。 从队列中取出当前格子,检查其四个方向的相邻格子。 如果相邻格子在网格范围内且未被访问过,更新其 black_count 并将其加入队列。 重复上述步骤,直到队列为空或到达终点 (n-1, m-1)。 代码框架:
from collections import deque
def solution(n: int, m: int, grid: list) -> int: # 定义四个方向的移动 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
# 初始化队列和visited数组
queue = deque([(0, 0)])
visited = [[False] * m for _ in range(n)]
black_count = [[float('inf')] * m for _ in range(n)]
# 起点初始化
black_count[0][0] = 0 if grid[0][0] == 0 else 1
visited[0][0] = True
while queue:
x, y = queue.popleft()
# 遍历四个方向
for dx, dy in directions:
nx, ny = x + dx, y + dy
# 检查是否在网格范围内
if 0 <= nx < n and 0 <= ny < m:
# 计算经过的黑色格子数量
new_black_count = black_count[x][y] + (1 if grid[nx][ny] == 1 else 0)
# 如果新的路径更优,更新并加入队列
if new_black_count < black_count[nx][ny]:
black_count[nx][ny] = new_black_count
queue.append((nx, ny))
# 返回终点的最少黑色格子数量
return black_count[n-1][m-1]
if name == 'main': print(solution(5, 3, [[0, 1, 0], [0, 1, 1], [0, 1, 0], [1, 0, 0], [1, 0, 0]]) == 1) print(solution(4, 4, [[0, 0, 1, 0], [1, 0, 1, 0], [1, 0, 0, 0], [1, 1, 1, 0]]) == 0) print(solution(3, 3, [[0, 0, 0], [1, 1, 0], [1, 1, 0]]) == 0)
关键步骤解释 方向数组:directions 用于表示四个方向的移动。 队列初始化:将起点 (0, 0) 加入队列,并初始化 visited 和 black_count。 BFS 循环:从队列中取出当前格子,遍历其四个方向的相邻格子,更新 black_count 并加入队列。 返回结果:最终返回终点的 black_count。 你可以根据这个框架继续完善代码,确保所有细节都正确处理。