leetcode542. 01 Matrix

題目要求

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.java

The distance between two adjacent cells is 1.算法

Example 1:數組

Input:rest

[[0,0,0],
 [0,1,0],
 [0,0,0]]

Output:code

[[0,0,0],
 [0,1,0],
 [0,0,0]]

Example 2:隊列

Input:element

[[0,0,0],
 [0,1,0],
 [1,1,1]]

Output:io

[[0,0,0],
 [0,1,0],
 [1,2,1]]

Note:ast

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

現有一個0和1構成的二維數組,要求計算每一位距離0最近的距離。加入當前值爲0,則距離0最近的距離就是0。class

思路一:BFS

廣度優先算法的核心思路在於,從每個最近的距離開始,不斷延展開去,直到全部的下標都找到了最近的值。
以第二個例子爲基礎,思路以下:

原始數組:
[[0,0,0],
 [0,1,0],
 [1,1,1]]
 
1. 先將全部非0的點的距離更新爲最大
[[0,0,0],
 [0,max,0],
 [max,max,max]]
 
2. 以全部原始距離爲0的點向外搜索一格,將當前距離大於0的最近距離更新爲1
[[0,0,0],
 [0,1,0],
 [1,max,1]]

3. 再將全部最近距離爲1的向外拓展一圈
[[0,0,0],
 [0,1,0],
 [1,2,1]]

至此全部的最近距離都已經得出。

廣搜一般都須要經過隊列來實現。代碼以下:

public int[][] updateMatrix(int[][] matrix) {  
    int row = matrix.length;  
    int column = matrix[0].length;  
    Queue<int[]> queue = new LinkedList<>();  
    for (int i = 0 ; i<row ; i++) {  
        for (int j = 0 ; j<column; j++) {  
            if (matrix[i][j] == 0) {  
                queue.offer(new int[]{i,j});  
            } else {  
                matrix[i][j] = Integer.MAX_VALUE;  
            }  
        }  
    }  
  
    int[][] directions = new int[][]{  
        {0,-1},  
        {-1,0},  
        {0,1},  
        {1,0}  
    };  
    while (!queue.isEmpty()) {  
        int[] cell = queue.poll();  
        for (int[] direction : directions) {  
            int neighbourRow = cell[0] + direction[0];  
            int neighbourColumn = cell[1] + direction[1];  
            if (neighbourRow < 0 || neighbourRow >= row || neighbourColumn < 0 || neighbourColumn >= column  
                || matrix[neighbourRow][neighbourColumn] <= matrix[cell[0]][cell[1]] + 1) {  
                continue;  
            }  
            queue.offer(new int[]{neighbourRow, neighbourColumn});  
            matrix[neighbourRow][neighbourColumn] = matrix[cell[0]][cell[1]] + 1;  
        }  
    }  
    return matrix;  
}

思路二:DFS

深度優先則是從最左上角節點開始,從左往右從上往下依次,對上下左右四個方向都進行最近距離的計算。這裏須要額外用一個數組來記錄結果值,從而防止出現重複判斷的狀況。好比:

[[0,0],
 [1,1],
 [1,1]]

若是不判斷當前節點是否訪問過,則會在全是1的子數組中無限遍歷,始終得不出最短距離。代碼以下:

public int[][] updateMatrix(int[][] matrix) {  
    int row = matrix.length;  
    int column = matrix[0].length;  
    int[][] result = new int[row][column];  
    for (int i = 0 ; i<row ; i++) {  
        for (int j = 0 ; j<column; j++) {  
            result[i][j] = updateMatrix(matrix, i, j, result);  
        }  
    }  
    return result;  
}  
  
public int updateMatrix(int[][] matrix, int i, int j, int[][] result) {  
    if (matrix[i][j] == 0) {  
        return 0;  
    }  
    if (i > 0 && matrix[i-1][j] == 0){  
        return 1;  
    }  
    if (j > 0 && matrix[i][j-1] == 0) {  
        return 1;  
    }  
    if (i < matrix.length-1 && matrix[i+1][j] == 0) {  
        return 1;  
    }  
    if (j < matrix[0].length - 1 && matrix[i][j+1] == 0) {  
        return 1;  
    }  
  
    int min = Integer.MAX_VALUE - 1;  
    if (i > 0 && result[i-1][j] != 0) {  
        min = Math.min(min, result[i-1][j]);  
    }  
    if (j > 0 && result[i][j-1] != 0) {  
        min = Math.min(min, result[i-1][j]);  
    }  
    if (i < matrix.length - 1) {  
        min = Math.min(min, updateMatrix(matrix, i+1, j, result));  
    }  
    if (j < matrix[0].length - 1) {  
        min = Math.min(min, updateMatrix(matrix, i, j+1, result));  
    }  
    return min + 1;  
}
相關文章
相關標籤/搜索