1. 程式人生 > 實用技巧 >BFS——1091. 二進位制矩陣中的最短路徑

BFS——1091. 二進位制矩陣中的最短路徑

在一個N ×N 的方形網格中,每個單元格有兩種狀態:空(0)或者阻塞(1)。

一條從左上角到右下角、長度為 k 的暢通路徑,由滿足下述條件的單元格C_1, C_2, ..., C_k組成:

相鄰單元格C_i 和C_{i+1}在八個方向之一上連通(此時,C_i 和C_{i+1}不同且共享邊或角)
C_1 位於(0, 0)(即,值為grid[0][0])
C_k位於(N-1, N-1)(即,值為grid[N-1][N-1])
如果 C_i 位於(r, c),則 grid[r][c]為空(即,grid[r][c] ==0)
返回這條從左上角到右下角的最短暢通路徑的長度。如果不存在這樣的路徑,返回 -1 。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/shortest-path-in-binary-matrix


思路:

找最短路徑問題,首先想到的就是BFS,如果是DFS,BFS一層一層往下遍歷,找到了就知道下面的是更深層次的,肯定比當前層次的要長

其次,看到底是八連通還是四連通,就是說斜邊能不能走,能走就是八連通,這題就是八連通,還要注意返回值是經過了多少個格子

class Solution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        //八連通的問題
int[][] DIR = { {1,0}, {-1,0}, {0,1}, {0,-1}, {1,1}, {1,-1}, {-1,1}, {-1,-1} }; //定義兩個變數來儲存長和寬 int R = grid.length; int C = grid[0].length;
//排除一些特殊情況 if (grid[0][0] == 1){ return -1; } if (R == 1 && C == 1){ return 1; } //準備工作 boolean[][]vis = new boolean[R][C]; int[][]path = new int[R][C]; Queue<Integer> queue = new LinkedList<>(); queue.add(0); vis[0][0]=true; path[0][0]=1; int r,c; while (!queue.isEmpty()){ Integer pos = queue.poll(); //一維陣列轉換為二維陣列的行和列 r = pos/C; // c = pos%C; // for (int d = 0; d < DIR.length; ++d) { int nr = r + DIR[d][0]; int nc = c + DIR[d][1]; if(inArea(nr,nc,grid) && !vis[nr][nc] && grid[nr][nc]!=1) { //記錄步長 path[nr][nc] = path[r][c]+1; //狀態改變 vis[nr][nc]=true; //此處再轉換為一維陣列 queue.add(nc+nr*C); //狀態壓縮 ---> (x,y) 轉移為 格子序號 if(nr==R-1 && nc == C-1) { //說明到達終點 return path[nr][nc]; } } } } return -1; } public boolean inArea(int r,int c,int[][] grid) { return r>=0&& r<grid.length && c>=0&& c<grid[0].length; } }