【LeetCode-搜索】01矩阵
题目描述
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例:
输入:
0 0 0
0 1 0
0 0 0
输出:
0 0 0
0 1 0
0 0 0
输入:
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1
题目链接: https://leetcode-cn.com/problems/01-matrix/
思路1
bfs可以找到从源点到终点的最短路径,所以对于一个位置,如果当前位置是0,则直接返回0;如果不是0,则使用bfs搜索到0的最短路径。代码如下:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
if(matrix.empty()) return {{}};
vector<vector<int>> ans;
for(int i=0; i<matrix.size(); i++){
vector<int> v;
for(int j=0; j<matrix[i].size(); j++){
v.push_back(bfs(matrix, i, j));
}
ans.push_back(v);
}
return ans;
}
int bfs(vector<vector<int>> matrix, int i, int j){
if(matrix[i][j]==0) return 0;
int rows = matrix.size();
int cols = matrix[0].size();
int visit[rows][cols];
memset(visit, 0, sizeof(visit));
int dirs[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
queue<int> qx, qy;
qx.push(i);
qy.push(j);
int dist = 1;
int curLevelNums = 1;
int nextLevelNums = 0;
while(!qx.empty()){
int x = qx.front(); qx.pop();
int y = qy.front(); qy.pop();
visit[x][y] = 1;
curLevelNums--;
for(int k=0; k<4; k++){
int tx = x+dirs[k][0];
int ty = y+dirs[k][1];
if(tx>=0 && tx<rows && ty>=0 && ty<cols){
if(matrix[tx][ty]==0){
return dist;
}else if(!visit[tx][ty]){
qx.push(tx);
qy.push(ty);
visit[tx][ty] = 1;
nextLevelNums++;
}
}
}
if(curLevelNums==0){
curLevelNums = nextLevelNums;
nextLevelNums = 0;
dist++; // 注意dist增加条件,使用类似于树层次打印的思想
}
}
return dist;
}
};
- 时间复杂度:O(n^2)
- 空间复杂度:O(n)
n为矩阵中元素的个数。
该方法由于时间复杂度过高导致超时未通过。
思路2
使用和思路1相反的思路。思路1是从非零值开始寻找到零值的最短路径,这样在每个非零的位置都要进行一次搜索,每个位置可能会入队列多次,而如果从0值开始寻找到非零值的距离,则每个节点只会入队列一次。为了从0值开始搜素,我们将所有0的位置加入到队列中,然后bfs。代码如下:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
if(matrix.empty()) return {{}};
int rows = matrix.size();
int cols = matrix[0].size();
int visit[rows][cols];
memset(visit, 0, sizeof(visit));
vector<vector<int>> dist(rows, vector<int>(cols));
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.emplace(i, j);
visit[i][j] = 1;
}
}
}
int dirs[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
while(!q.empty()){
auto [i, j] = q.front(); q.pop();
for(int k=0; k<4; k++){
int x = i+dirs[k][0];
int y = j+dirs[k][1];
if(x>=0 && x<rows && y>=0 && y<cols && !visit[x][y]){
dist[x][y] = dist[i][j]+1;
visit[x][y] = 1;
q.emplace(x, y);
}
}
}
return dist;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(n)
n为矩阵中元素的个数。