总结leetcode75中的图广度优先搜索算法题解题思路。
上一篇:力扣75——图深度优先搜索
力扣75——图广度优先搜索
- 1 迷宫中离入口最近的出口
- 2 腐烂的橘子
- 1-2 解题总结
1 迷宫中离入口最近的出口
题目:
给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 '.' 表示)
和墙(用 '+' 表示)。同时给你迷宫的入口 entrance ,用 entrance = [entrancerow, entrancecol] 表示你一开始所在格子的行和列。
每一步操作,你可以往 上,下,左 或者 右 移动一个格子。你不能进入墙所在的格子,
你也不能离开迷宫。你的目标是找到离 entrance 最近 的出口。出口 的含义是 maze
边界 上的 空格子。entrance 格子 不算 出口。请你返回从 entrance 到最近出口的最短路径的 步数 ,如果不存在这样的路径,请你返回 -1 。
题解:
广度优先搜索。
将与入口相邻的空格子压入队列。
然后用while循环
遍历队列中的格子,每个访问过的格子都要做标记(记录它到入口的距离,并将状态设置为已访问)。
如果当前格子为出口,则返回距离d+1
。
如果访问玩所有格子,则返回-1
。
class Solution {
public:int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {int m = maze.size();int n = maze[0].size();// 上下左右四个相邻坐标对应的行列变化量vector<int> dx = {1, 0, -1, 0};vector<int> dy = {0, 1, 0, -1};queue<tuple<int, int, int>> q;// 入口加入队列并修改为墙q.emplace(entrance[0], entrance[1], 0);maze[entrance[0]][entrance[1]] = '+';while (!q.empty()){auto [cx, cy, d] = q.front();q.pop();// 遍历四个方向相邻坐标for (int k = 0; k < 4; ++k){int nx = cx + dx[k];int ny = cy + dy[k];// 新坐标合法且不为墙if (nx >= 0 && nx < m && ny >= 0 && ny < n && maze[nx][ny] == '.'){if (nx == 0 || nx == m - 1 || ny == 0 || ny == n - 1){// 新坐标为出口,返回距离作为答案return d + 1;}// 新坐标为空格子且不为出口,修改为墙并加入队列maze[nx][ny] = '+';q.emplace(nx, ny, d + 1);}}}// 不存在到出口的路径,返回 -1return -1;}
};
2 腐烂的橘子
题目:
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。
题解:
广度优先搜索。
定义矩阵dis
,记录每个橘子是从第几天开始腐烂的。-1表示未腐烂或者没有橘子。
先找出所有腐烂的句子,并将其位置存入队列Q
。
while
遍历Q
中的烂橘子,如果烂橘子grid[i][j]
的周围有未腐烂的橘子,则将对应的dis值改为dis[i][j]+1
,并将该橘子的位置压入队列Q
。
Q为空之后,查看是否全部腐烂。
class Solution {int cnt;int dis[10][10];int dir_x[4]={0, 1, 0, -1};int dir_y[4]={1, 0, -1, 0};
public:int orangesRotting(vector<vector<int>>& grid) {queue<pair<int,int> >Q;memset(dis, -1, sizeof(dis));cnt = 0;int n=(int)grid.size(), m=(int)grid[0].size(), ans = 0; for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){if (grid[i][j] == 2){Q.push(make_pair(i, j));dis[i][j] = 0;}else if (grid[i][j] == 1) cnt += 1;}}while (!Q.empty()){pair<int,int> x = Q.front();Q.pop();for (int i = 0; i < 4; ++i){int tx = x.first + dir_x[i];int ty = x.second + dir_y[i];if (tx < 0|| tx >= n || ty < 0|| ty >= m|| dis[tx][ty]!=-1 || !grid[tx][ty]) continue;dis[tx][ty] = dis[x.first][x.second] + 1;Q.push(make_pair(tx, ty));cnt -= 1;ans = dis[tx][ty];if (!cnt) break;}}return cnt ? -1 : ans;}
};
1-2 解题总结
题目共同的特点:从起始节点出发,搜索并记录某个或全部节点到起始节点的距离。
是否能用深度优先搜索:不能,因为有些节点可以通过多条路径到达起始节点,如果用深度优先搜索,不能保证某条深度搜索路径算出来的距离是该节点的最短距离。