写在前面:本文题单均来自力扣的算法刷题计划,开这个系列主要是以题目与题解的形式对一些常见、常用算法进行归类和总结,希望在促进自己学习的同时也能帮助到看到这篇文章的大家。另外,本文并非一天一更~
目录
题目一:542. 01 矩阵
题目描述:
题目分析:
这题运用BFS可以求解,我们可以先创建一个ret数组记录mat数组里每个数到0的最短距离,将mat数组里为0的数都在其内记录为0,为1的数暂且将其到0的距离记录为一个较大的数(不小于m*n),接着创建一个队列que,对mat中的每一个0依次入队,再逐一将其上下左右拓展,若遇到1时,也就是当前位置在ret内记录的距离大于上一步的位置在ret内记录的距离时,取上一步的位置在ret内记录的距离再+1,保证为最短距离,每一个位置拓展完后再出队即可。
题解代码:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat)
{
int r=mat.size(); //mat数组的长、宽
int c=mat[0].size();
vector<pair<int,int>> step={{0,-1},{0,1},{-1,0},{1,0}};
vector<vector<int>> ret(r,vector<int>(c,INT_MAX)); //初始化ret数组
queue<pair<int,int>> que;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(mat[i][j]==0)
{
ret[i][j]=0; //记录0到0的最短距离就是0
que.push({i,j}); //将所有0入队
}
}
}
while(!que.empty())
{
auto temp=que.front(); //auto自动识别数据类型
que.pop();
for(int i=0;i<4;i++) //进行拓展
{
int x=temp.first+step[i].first;
int y=temp.second+step[i].second;
if(x<r && y<c && x>=0 && y>=0) //防止越界
{
if(ret[x][y]>ret[temp.first][temp.second]+1) //遇到1了
{
ret[x][y]=ret[temp.first][temp.second]+1;
que.push({x,y}); //出队
}
}
}
}
return ret;
}
};
题目二:994. 腐烂的橘子
题目描述:
题目分析:
经典BFS问题,先将所有腐烂的橘子入队,再同时向上下左右扩散,遇到新鲜的橘子使其腐烂,以此类推,最后再判断有无新鲜的橘子即可。
题解代码:
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid)
{
int r = grid.size();
int c = grid[0].size();
vector<pair<int, int>> step = { {-1,0},{1,0},{0,1},{0,-1} };
queue<pair<int, int>> que;
for (int i = 0; i < r; i++) //初始化队列
{
for (int j = 0; j < c; j++)
{
if (grid[i][j] == 2)
{
que.push({ i,j });
}
}
}
int time = 0;
while (!que.empty())
{
int size=que.size();
while(size--) //当前一波腐烂的橘子同时进行扩散
{
auto temp = que.front();
que.pop();
for (int i = 0; i < 4; i++) //开始扩散
{
int x = temp.first + step[i].first;
int y = temp.second + step[i].second;
if (x >= 0 && x < r && y >= 0 && y < c)
{
if (grid[x][y] == 1)
{
grid[x][y] = 2;
que.push({ x,y });
}
}
}
}
if (!que.empty()) //扩散一轮后计时
time++;
}
for (int i = 0; i < r; i++) //最后再判断还有无新鲜橘子
{
for (int j = 0; j < c; j++)
{
if (grid[i][j] == 1)
return -1;
}
}
return time;
}
};