给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例 1:
输入:
0 0 0 0 1 0 0 0 0
输出:
0 0 0 0 1 0 0 0 0
示例 2:
输入:
0 0 0 0 1 0 1 1 1
输出:
0 0 0 0 1 0 1 2 1
注意:
- 给定矩阵的元素个数不超过 10000。
- 给定矩阵中至少有一个元素是 0。
- 矩阵中的元素只在四个方向上相邻: 上、下、左、右。
思路:
1.广度优先搜索,对于每一个1节点来说,要找距离最近的点,先找出上下左右四个方向的点,加入队列中。
对于队列中的每个元素,判断是否为零,为零则结束搜索,设置距离。不为零就将其周围的点加入到队列中。
Code:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m=matrix.size();
int n = matrix[0].size();
vector<vector<int> >dp(m,vector<int>(n,5));
pair<int,int>index;
bool flag=false;;
for(int i=0;i<=m;i++)
for(int j=0;j<=n;j++)
{
queue< pair<int,int> >que;
flag=false;int dep=0;
que.push(make_pair(i,j));
while(!que.empty()){
if(flag)break;
int num=que.size();
while(num--)
{
index=que.front();
que.pop();
int row=index.first;
int col=index.second;
if(row<0||row>=m||col<0||col>=n)continue;
if(matrix[row][col]==0){dp[i][j]=dep;flag=true;break;}
else{ que.push(make_pair(row-1,col));
que.push(make_pair(row+1,col));
que.push(make_pair(row,col-1));
que.push(make_pair(row,col+1));
}
}
dep++;
}
}
return dp;
}
};
思路二:
我们首先建立一个和matrix大小相等的矩阵res,初始化为很大的值,这里我们用INT_MAX-1,为甚么要减1呢,后面再说。然后我们遍历matrix矩阵,当遇到为0的位置,我们将结果res矩阵的对应位置也设为0,这make sense吧,就不多说了。然后就是这个解法的精髓了,如果不是0的地方,我们在第一次扫描的时候,比较其左边和上边的位置,取其中较小的值,再加上1,来更新结果res中的对应位置。这里就明白了为啥我们要初始化为INT_MAX-1了吧,因为这里要加1,如果初始化为INT_MAX就会整型溢出,不过放心,由于是取较小值,res[i][j]永远不会取到INT_MAX,所以不会有再加1溢出的风险。第一次遍历我们比较了左和上的方向,那么我们第二次遍历就要比较右和下的方向,注意两种情况下我们不需要比较,一种是当值为0时,还有一种是当值为1时,这两种情况下值都不可能再变小了,所以没有更新的必要,参见代码如下:
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int n = matrix.size(), m = matrix[0].size();
vector<vector<int> >ans(n, vector<int>(m, INT_MAX-1));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(matrix[i][j] == 0)
ans[i][j] = 0;
else
{
ans[i][j] = min(ans[i][j], ans[i][max(0,j-1)]+1);
ans[i][j] = min(ans[i][j], ans[max(0,i-1)][j]+1);
}
}
}
for(int i=n-1;i>=0;i--)
{
for(int j=m-1;j>=0;j--)
{
if(matrix[i][j] == 0)
ans[i][j] = 0;
else
{
ans[i][j] = min(ans[i][j], ans[min(i+1, n-1)][j]+1);
ans[i][j] = min(ans[i][j], ans[i][min(j+1, m-1)]+1);
}
}
}
return ans;
}
};