LeetCode矩阵题——用辐射来理解
542. 01 矩陣
給定一個由 0 和 1 組成的矩陣,找出每個元素到最近的 0 的距離。兩個相鄰元素間的距離為 1 。
示例 1:
輸入:
輸出:
0 0 0 0 1 0 0 0 0示例 2:
輸入:
輸出:
0 0 0 0 1 0 1 2 1注意:
給定矩陣的元素個數(shù)不超過 10000。
給定矩陣中至少有一個元素是 0。
矩陣中的元素只在四個方向上相鄰: 上、下、左、右。
分析:
想法一:廣度優(yōu)先搜索
【注】要先把 matrix 數(shù)組中 1 的位置設(shè)置成 -1 (或無效的距離值)
廣度優(yōu)先搜索
找每個元素到最近的 0 的距離,即為,0到該元素的最短距離。可將0視作源點進行輻射。輻射過程如圖所示。
1.紅色為源點。
2.橙色為輻射第一圈。
3.黃色為輻射第二圈。(因此該其值為2)
由圖可知,
1.將源點0(紅色)入隊,并將終點(即非0點,元素點)值改為-1,(-1為未訪問)
2.將隊列中結(jié)點彈出,并在四個方向輻射,向左向右向上向下(方向矢量為左(-1,0)右(1,0)上(0,-1)下(0,1)),得到輻射第一圈結(jié)點。并將輻射第一圈結(jié)點值改為1。
3.將輻射第一圈結(jié)點入隊,然后依次彈出,并在四個方向輻射(忽略源點方向,即只往-1方向輻射),得到輻射第二圈結(jié)點。并將輻射第二圈結(jié)點值改為2。
…
重復執(zhí)行上述步驟,直至隊列為空
4.返回新的matrix矩陣
public class T542 {public int [][] updateMatrix(int[][] matrix){Queue<int[]> queue=new LinkedList<>();for (int i = 0; i < matrix.length; i++) {for(int j=0;j<matrix[0].length;j++){if(matrix[i][j]==0){queue.offer(new int[]{i,j});//0元素入隊}else {matrix[i][j]=-1;//-1為未訪問標記}}}//dx,dy表示坐標系中x,y向左、向右、向上、向下的分量int[] dx=new int[]{-1,1,0,0};int[] dy=new int[]{0,0,-1,1};while (!queue.isEmpty()){int[] point=queue.poll();//0元素出隊int x=point[0],y=point[1];for (int i = 0; i < 4; i++) {//彈出的0元素向四個方向移動后的新坐標int newX=x+dx[i];int newY=y+dy[i];// 如果四鄰域的點是 -1,表示這個點是未被訪問過的 1// 所以這個點到 0 的距離就可以更新成 matrix[x][y] + 1。if (newX >= 0 && newX < matrix.length && newY >= 0 && newY < matrix[0].length//判斷是否超出數(shù)組邊界&& matrix[newX][newY] == -1) {//判斷新坐標是否為終點-1matrix[newX][newY] = matrix[x][y] + 1;//將終點值-1,改為源點值+1queue.offer(new int[] {newX, newY});//將終點坐標加入隊列,進行第二輪的輻射}}}return matrix;}}第二種
class Solution {public int[][] updateMatrix(int[][] matrix) {// 首先將 0 邊上的 1 入隊int[] dx = new int[] {-1, 1, 0, 0};int[] dy = new int[] {0, 0, -1, 1};Queue<int[]> queue = new LinkedList<>();int m = matrix.length, n = matrix[0].length;int[][] res = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (matrix[i][j] == 0) {for (int k = 0; k < 4; k++) {int x = i + dx[k];int y = j + dy[k];if (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] == 1 && res[x][y] == 0) {// 這是在 0 邊上的1。需要加上 res[x][y] == 0 的判斷防止重復入隊res[x][y] = 1;queue.offer(new int[] {x, y});}}}}}while (!queue.isEmpty()) {int[] point = queue.poll();int x = point[0], y = point[1];for (int i = 0; i < 4; i++) {int newX = x + dx[i];int newY = y + dy[i];if (newX >= 0 && newX < m && newY >= 0 && newY < n && matrix[newX][newY] == 1 && res[newX][newY] == 0) {res[newX][newY] = res[x][y] + 1;queue.offer(new int[] {newX, newY});}}}return res;} }動態(tài)規(guī)劃
class Solution {public int[][] updateMatrix(int[][] matrix) {int m = matrix.length, n = matrix[0].length;int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {dp[i][j] = matrix[i][j] == 0 ? 0 : 10000;}}// 從左上角開始for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i - 1 >= 0) {dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + 1);}if (j - 1 >= 0) {dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + 1);}}}// 從右下角開始for (int i = m - 1; i >= 0; i--) {for (int j = n - 1; j >= 0; j--) {if (i + 1 < m) {dp[i][j] = Math.min(dp[i][j], dp[i + 1][j] + 1);}if (j + 1 < n) {dp[i][j] = Math.min(dp[i][j], dp[i][j + 1] + 1);}}}return dp;} }總結(jié)
以上是生活随笔為你收集整理的LeetCode矩阵题——用辐射来理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 找不到任何设备驱动程序.请确保安装介质_
- 下一篇: 利用PowerDesigner逆向工程抓