方法一:bfs
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
if (matrix.empty()) return matrix;
int rows = matrix.size(),cols = matrix[0].size();
vector<vector<int>> dist(rows, vector<int>(cols)); //距离矩阵
vector<vector<int>> seen(rows, vector<int>(cols)); //访问标记矩阵
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; //方向数组
queue<pair<int, int>> q;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
if (matrix[i][j] == 0) { //所有0点位置放入队列
seen[i][j] = 1; //并标记为访问过
q.push({ i, j });
}
while (!q.empty()) {
pair<int,int> cur=q.front();
q.pop();
for (int i = 0; i < 4; i++) { //四个方向搜索
int nx=cur.first+dir[i][0], ny=cur.second+dir[i][1];
if (nx>=0 && ny>=0 && nx<rows && ny<cols && !seen[nx][ny]){//未访问位置
dist[nx][ny]=dist[cur.first][cur.second]+1; //更新距离
q.push({nx,ny});
seen[nx][ny]=1; //标记为访问过
}
}
}
return dist;
}
};
优化
为减少空间,可以直接在原矩阵上操作,未访问位置设置标记位。访问时,更新距离。
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
if (matrix.empty()) return matrix;
int rows = matrix.size(),cols = matrix[0].size();
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; //方向数组
queue<pair<int, int>> q;
for (int i = 0; i < rows; i++) //所有0点位置放入队列
for (int j = 0; j < cols; j++)
if (matrix[i][j] == 0)
q.push({i,j});
else
matrix[i][j]=-1; //并标记为 未访问
while (!q.empty()) {
pair<int,int> cur=q.front();
q.pop();
for (int i = 0; i < 4; i++) { //四个方向搜索
int nx=cur.first+dir[i][0], ny=cur.second+dir[i][1];
if (nx>=0 && ny>=0 && nx<rows && ny<cols && matrix[nx][ny]==-1){ //未访问位置
matrix[nx][ny]=matrix[cur.first][cur.second]+1; //更新距离
q.push({nx,ny});
}
}
}
return matrix;
}
};