[Leedcode][JAVA][第1162题][BFS]
生活随笔
收集整理的這篇文章主要介紹了
[Leedcode][JAVA][第1162题][BFS]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【問題描述】
你現在手里有一份大小為?N x N 的『地圖』(網格)?grid,上面的每個『區域』(單元格)都用?0?和?1?標記好了。其中?0?代表海洋,1?代表陸地,你知道距離陸地區域最遠的海洋區域是是哪一個嗎?請返回該海洋區域到離它最近的陸地區域的距離。我們這里說的距離是『曼哈頓距離』(?Manhattan Distance):(x0, y0) 和?(x1, y1)?這兩個區域之間的距離是?|x0 - x1| + |y0 - y1|?。如果我們的地圖上只有陸地或者海洋,請返回?-1。示例 1: 輸入:[[1,0,1],[0,0,0],[1,0,1]] 輸出:2提示:1 <= grid.length == grid[0].length?<= 100 grid[i][j]?不是?0?就是?1示例 1:
輸入:[[1,0,1],[0,0,0],[1,0,1]]
輸出:2
解釋: 海洋區域 (1, 1) 和所有陸地區域之間的距離都達到最大,最大距離為 2。
【解答思路】
1. (威威的工程)BFS
- 多個陸地起點入隊列 ,彈出的同時向四周摸索,每次距離+1
時間復雜度:O(N^2) 空間復雜度:O(N^2)
public int maxDistance(int[][] grid) {//方向向量int [][] directions = {{1,0},{-1,0},{0,1},{0,-1}};int N = grid.length;Queue<Integer> queue = new LinkedList<>();for(int i= 0 ; i< N; i++){for(int j= 0 ; j < N; j++){if(grid[i][j]==1){queue.add(getIndex(i,j,N));}} }int size= queue.size();//全部是0或者全部是1 全海洋或全陸地if(size==0 || size == N*N){return -1;}int step = 0;while (!queue.isEmpty()){int currentQueueSize = queue.size();for(int i=0 ;i<currentQueueSize;i++){Integer head = queue.poll();//巧妙一個數存放一個二維坐標int currentX = head / N;int currentY = head % N;for(int[] direction :directions){int newX = currentX+direction[0];int newY = currentY+direction[1];if(inArea(newX,newY,N) && grid[newX][newY]==0){//擴充海洋部分 賦值任何非0數 最后只關注最長路徑grid[newX][newY] =1;queue.add(getIndex(newX,newY,N));}}}step++;}//最后一部沒有擴散 但step++仍然執行 故最后結果需要-1return step-1;}/*** @param x 二維表格單元格橫坐標* @param y 二維表格單元格縱坐標* @param cols 二維表格列數* @return*/private int getIndex(int x, int y, int cols) {return x * cols + y;}/*** @param x 二維表格單元格橫坐標* @param y 二維表格單元格縱坐標* @param N 二維表格行數(列數)* @return 是否在二維表格有效范圍內*/private boolean inArea(int x, int y, int N) {return 0 <= x && x < N && 0 <= y && y < N;} 作者:liweiwei1419 鏈接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/yan-du-you-xian-bian-li-java-by-liweiwei1419/?###### 2. (甜姨的刀法)BFS
- 多個陸地起點入隊列 ,彈出的同時向四周摸索,每次距離+1
時間復雜度:O(N^2) 空間復雜度:O(N^2)
public int maxDistance(int[][] grid) {int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};Queue<int[]> queue = new ArrayDeque<>();int m = grid.length, n = grid[0].length;// 先把所有的陸地都入隊。for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 1) {queue.offer(new int[] {i, j});}}}// 從各個陸地開始,一圈一圈的遍歷海洋,最后遍歷到的海洋就是離陸地最遠的海洋。boolean hasOcean = false;int[] point = null;while (!queue.isEmpty()) {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 || grid[newX][newY] != 0) {continue;}grid[newX][newY] = grid[x][y] + 1; // 這里我直接修改了原數組,因此就不需要額外的數組來標志是否訪問hasOcean = true;queue.offer(new int[] {newX, newY});}}// 沒有陸地或者沒有海洋,返回-1。if (point == null || !hasOcean) {return -1;}// 返回最后一次遍歷到的海洋的距離。return grid[point[0]][point[1]] - 1;}作者:sweetiee 鏈接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/jian-dan-java-miao-dong-tu-de-bfs-by-sweetiee/【總結】
1. BFS
- 如果題目要求返回的結果和距離相關,需要在 while 循環內部一下子把當前列表的所有元素都依次取出來,這種「一下子」操作的次數就是我們需要的距離;
- 如果一個單元格被添加到隊列以后,需要馬上將它標記為已經訪問(根據情況,可以直接在原始輸入數組上修改,也可以使用一個布爾數組 visited 進行標記),否則很可能會出現死循環
2.樹與無向圖的BFS
- 樹只有一個root ,無向圖有多個源點
- 樹是有向的 不需要標注是否訪問過,無向圖需要標記是否訪問過且需要在入隊之前設置為已訪問(防止節點重復入隊)!
3. 二維表格上編碼代碼的常用技巧
- 設置方向數組
- 設置是否越界的判斷函數 inArea()
- 根據情況,使用二維坐標和一維坐標相互轉換的操作,因為二維坐標傳入隊列的時候,需要封裝成數組,創建和銷毀數組有一定性能消耗
總結
以上是生活随笔為你收集整理的[Leedcode][JAVA][第1162题][BFS]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【TODO】每日时间工作总结记录模板
- 下一篇: Oracle data type num