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
現有一個0和1構成的二維數組,要求計算每一位距離0最近的距離。加入當前值爲0,則距離0最近的距離就是0。class
廣度優先算法的核心思路在於,從每個最近的距離開始,不斷延展開去,直到全部的下標都找到了最近的值。
以第二個例子爲基礎,思路以下:
原始數組: [[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; }
深度優先則是從最左上角節點開始,從左往右從上往下依次,對上下左右四個方向都進行最近距離的計算。這裏須要額外用一個數組來記錄結果值,從而防止出現重複判斷的狀況。好比:
[[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; }