在二维矩阵中一次走 2 步

Take 2 steps at a time in a 2d matrix

给你一个 MxN 二维网格,用这三个可能的值初始化。

-1 - 一堵墙或障碍物。

0 - 门。

INF - 无限意味着一个空房间

用到最近大门的距离填充每个空房间。

例如,给定二维网格:

INF  -1  0  INF
INF INF INF  -1
INF  -1 INF  -1
0    -1 INF INF

运行函数后,二维网格应该是:

3  -1   0   1
2   2   1  -1
1  -1   2  -1
0  -1   3   4

我用的是BFS,从每个0(门)开始,不断更新每个INF的最小值。下面是我的代码,它有效。

public void wallsAndGates(int[][] rooms) {
    if(rooms==null || rooms.length==0) return;
    int row=rooms.length;
    int col=rooms[0].length;
    Queue<Integer> q=new LinkedList<Integer>();
    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++){
            if(rooms[i][j]==0) {
                boolean[][] visited=new boolean[row][col];
                q.add(i*col+j);
                bfs(rooms,q,visited);
            }
        }
    }
}  

public void bfs(int[][] rooms, Queue<Integer> q, boolean[][] visited){
    int row=rooms.length;
    int col=rooms[0].length;
    int distance=1;
    while(!q.isEmpty()){
        int size=q.size();
        for(int m=0; m<size; m++){
            int num=q.poll();
            int i=num/col;
            int j=num%col;
            if(j-1>=0 && rooms[i][j-1]!=0 && rooms[i][j-1]!=-1 && !visited[i][j-1]){
                rooms[i][j-1]=Math.min(rooms[i][j-1],distance);
                q.add(i*col+j-1);
                visited[i][j-1]=true;
            }
            if(j+1<rooms[0].length && rooms[i][j+1]!=0 && rooms[i][j+1]!=-1 && !visited[i][j+1]){
                rooms[i][j+1]=Math.min(rooms[i][j+1],distance);
                q.add(i*col+j+1);
                visited[i][j+1]=true;
            }
            if(i-1>=0 && rooms[i-1][j]!=0 && rooms[i-1][j]!=-1 && !visited[i-1][j]){
                rooms[i-1][j]=Math.min(rooms[i-1][j],distance);
                q.add((i-1)*col+j);
                visited[i-1][j]=true;
            }
            if(i+1<rooms.length && rooms[i+1][j]!=0 && rooms[i+1][j]!=-1 && !visited[i+1][j]){
                rooms[i+1][j]=Math.min(rooms[i+1][j],distance);
                q.add((i+1)*col+j);
                visited[i+1][j]=true;
            }
       }
       distance++;
    }
}

但是,如果我们可以一次执行 2 个步骤,如 "left left" 或 "right up",会怎样呢?那么如何计算每个INF到它最近的门(0)的距离呢?我们还能使用 BFS 吗?

当然可以。现在您正在测试坐标:

(i+1, j)
(i,   j+1)
(i-1, j)
(i,   j-1)

对应于紧靠 (i, j) 的北、南、东、西的值。只需添加以下测试:

(i+1, j+1)
(i-1, j-1)
(i+1, j-1)
(i-1, j+1)

对应于(i, j)周围的对角线。

编辑:原文看错了post。您还需要添加任何其他可能的组合,例如 (i+2, j),它对应于 "right right"。在开始之前绘制可能结果的图表并列出完整列表将很有帮助。

小心一点。您的代码很乱,添加这四个语句时很容易出错。慢慢来,仔细检查你的工作。