题目描述
解法一:BFS(C++)
详细分析参考 甜姨
下面是算法核心:
首先把每个源点 0 入队,然后从各个 0 同时开始一圈一圈的向 1 扩散(每个 1 都是被离它最近的 0 扩散到的 ),扩散的时候可以设置 来记录距离(即扩散的层次)并同时标志是否访问过。对于本题是可以直接修改原数组 来记录距离和标志是否访问的,这里要注意先把 matrix 数组中 1 的位置设置成 -1
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
queue<pair<int, int>> q;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(matrix[i][j]==0)
q.emplace(i, j);
else
matrix[i][j] = -1;
}
}
vector<int> dx = {-1, 1, 0, 0};
vector<int> dy = {0, 0, -1, 1};
while(!q.empty())
{
auto [x, y] = q.front();
q.pop();
for(int i=0;i<4;i++)
{
int newx = x+dx[i];
int newy = y+dy[i];
// 如果四邻域的某点是-1,表示这个点是未被访问过的1
// 所以这个点到0的距离就可以更新成matrix[x][y]+1
if(newx>=0 && newx<m && newy>=0 && newy<n && matrix[newx][newy]==-1)
{
matrix[newx][newy] = matrix[x][y] + 1;
q.emplace(newx, newy);
}
}
}
return matrix;
}
};
解法二:动态规划(C++)
详细分析参考 甜姨
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<vector<int>> dp(m, vector<int>(n));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
dp[i][j] = (matrix[i][j]==0)?0:1000;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i-1>=0)
dp[i][j] = min(dp[i][j], dp[i-1][j]+1);
if(j-1>=0)
dp[i][j] = min(dp[i][j], dp[i][j-1]+1);
}
}
for(int i=m-1;i>=0;i--)
{
for(int j=n-1;j>=0;j--)
{
if(i+1<m)
dp[i][j] = min(dp[i][j], dp[i+1][j]+1);
if(j+1<n)
dp[i][j] = min(dp[i][j], dp[i][j+1]+1);
}
}
return dp;
}
};