我的思路跟ac代码是一样的,但是在处理队列,入点进去的时候就有问题了。所以20个测试用例只过了19个。
解决
首先你要知道这道题是解决什么问题,用什么方法。它是解决路径问题,多个起点,终点也不定。所以用bfs。
而我的问题就出现在入对的点不对,应该是起点入队,也就是0入队,到达1的时候就是最短路径bfs,或者说是0周围的1入队,这样一个思路。要思考是谁去入队才能遍历对。
bfs模板
bfs有两个模板,如下:
BFS 使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。BFS 总共有两个模板:
如果不需要确定当前遍历到了哪一层,BFS 模板如下。
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
如果要确定当前遍历到了哪一层,BFS 模板如下。 这里增加了 level 表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size 表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
代码
bfs解法,用时会较长
class Solution {
class pair {
int x, y;
public pair(int x, int y) {
this.x = x;
this.y = y;
}
}
int[] dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};
public int[][] updateMatrix(int[][] mat) {
ArrayDeque<pair> q = new ArrayDeque<>();
int n = mat.length, m = mat[0].length;
int[][] ans = new int[n][m];
for(int i = 0;i < n;i ++) {
for(int j = 0;j < m;j ++) {
if(mat[i][j] == 0) {
q.offer(new pair(i, j));
}
}
}
while(!q.isEmpty()) {
pair p = q.poll();
int x = p.x;
int y = p.y;
for(int i = 0;i < 4;i ++) {
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || ny < 0 || nx >= n || ny >= m
|| mat[nx][ny] == 0 || ans[nx][ny] != 0) continue;
ans[nx][ny] = ans[x][y] + 1;
q.offer(new pair(nx, ny));
}
}
return ans;
}
}
动态规划解法,很漂亮的写法;
class Solution {
public int[][] updateMatrix(int[][] mat) {
int n = mat.length;
int m = mat[0].length;
// 初始化距离矩阵,将非零元素距离初始化为一个较大的值
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
mat[i][j] = mat[i][j] == 0 ? 0 : Integer.MAX_VALUE / 2;
}
}
// 从左上角开始,从上到下,从左到右地更新距离矩阵
// 先从左上到右下遍历,再从右下到左上遍历,确保更新的距离是最小的
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i > 0) {
mat[i][j] = Math.min(mat[i][j], mat[i - 1][j] + 1);
}
if (j > 0) {
mat[i][j] = Math.min(mat[i][j], mat[i][j - 1] + 1);
}
}
}
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
if (i < n - 1) {
mat[i][j] = Math.min(mat[i][j], mat[i + 1][j] + 1);
}
if (j < m - 1) {
mat[i][j] = Math.min(mat[i][j], mat[i][j + 1] + 1);
}
}
}
return mat;
}
}