给定一个由 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
注意:
这道题应用的是广度优先搜索(BFS算法),是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。
BFS算法,一般是用队列实现,先进先出。其主要原理是,使用队列保存未被查询过的结点。
最简单的例子就是:我们丢了东西,首先会在自己的周围找,如果周围没找到,那么就会想远一点的地方,然后去找。
下面是BFS算法的常用模块:
BFS:
#include
#include
#include
#include
using namespace std;
const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量
struct State // BFS 队列中的状态数据结构
{
int x,y; // 坐标位置
int Step_Counter; // 搜索步数统计器
};
State a[maxn];
bool CheckState(State s) // 约束条件检验
{
if(!vst[s.x][s.y] && ...) // 满足条件
return 1;
else // 约束条件冲突
return 0;
}
void bfs(State st)
{
queue q; // BFS 队列
State now,next; // 定义2 个状态,当前和下一个
st.Step_Counter=0; // 计数器清零
q.push(st); // 入队
vst[st.x][st.y]=1; // 访问标记
while(!q.empty())
{
now=q.front(); // 取队首元素进行扩展
if(now==G) // 出现目标态,此时为Step_Counter 的最小值,可以退出即可
{
...... // 做相关处理
return;
}
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
next.y=now.y+dir[i][1];
next.Step_Counter=now.Step_Counter+1; // 计数器加1
if(CheckState(next)) // 如果状态满足约束条件则入队
{
q.push(next);
vst[next.x][next.y]=1; //访问标记
}
}
q.pop(); // 队首元素出队
}
return;
}
int main()
{
......
return 0;
}
对于此题,我们用java来写。我们分析道,题目要求必须含有零,那么我们可以把所有0入队,把1置为MAX_VALUE,然后把最靠近0的1的距离算出来,然后将他们入队,再算距离最靠近0的1的1的距离算出来,依次处理
class Solution {
public List> updateMatrix(List> matrix) {
if (matrix == null || matrix.size() == 0)
return matrix;
int m = matrix.size();
int n = matrix.get(0).size();
Queue q = new LinkedList<>();
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) {
// 把0元素加入队列中,以备波及影响周围元素
if (matrix.get(i).get(j) == 0)
q.offer(new int[] { i, j });
else
// 设为最大值,方便求0元素影响值
matrix.get(i).set(j, Integer.MAX_VALUE);
}
// 上下左右
int[][] dirs = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
while (!q.isEmpty()) {
int cell[] = q.poll();
for (int[] d : dirs) {
int row = cell[0] + d[0];
int col = cell[1] + d[1];
if (row < 0 || row >= m || col < 0 || col >= n)
continue;
// 上下左右取到的值
int value = matrix.get(row).get(col);
int tmp = matrix.get(cell[0]).get(cell[1]) + 1;
// 如果value小,那说明之前已经更新过,不是max
if (value <= tmp)
continue;
q.offer(new int[] { row, col });
matrix.get(row).set(col, tmp);
}
}
return matrix;
}
}
def updateMatrix(self, matrix):
if not matrix or not matrix[0]: return matrix
M, N = len(matrix), len(matrix[0])
cur = set()
for i in range(M):
for j in range(N):
if matrix[i][j] == 1:
for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if -1 < ni < M and -1 < nj < N and matrix[ni][nj] == 0:
cur.add((i, j))
matrix[i][j] = -1
break
distance = 1
while cur:
nxt = set()
distance += 1
for i, j in cur:
for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if -1 < ni < M and -1 < nj < N and matrix[ni][nj] == 1:
matrix[ni][nj] = distance
nxt.add((ni, nj))
cur = nxt
for i in range(M):
for j in range(N):
if matrix[i][j] == -1:
matrix[i][j] = 1
return matrix