廣度優先搜尋(BFS)理解
阿新 • • 發佈:2021-06-28
一.基本概念
廣度優先搜尋就是一種通過逐層遍歷所有訪問隊形,從而找到通過最短節點數到達目標的演算法。、
主要用於解決在一個無加權圖下找到從起點S到指定點W的最短路徑。
二.基本理解
如下圖所示, 要尋找從節點0到節點節點3的最短路徑,在第一輪搜尋中會把節點1、2、5當做搜尋物件,在第二輪搜尋中會把節點2、3、4當做搜尋物件,此時,找到目標節點3,所以從節點0到節點3的最短路徑為2,這就是BFS的基本原理;可能有人會問,為什麼在第二次搜尋中還會搜尋到2,這是因為雖然在第一次搜尋中經過了節點2,但是是作為0的下一層節點進行搜尋的,第二次搜尋節點2是作為節點1的下一層節點進行搜尋的(在實際的演算法實現過程中,會直接將2標記為已經遍歷,避免第二次重複搜尋)
圖片來源:https://zhuanlan.zhihu.com/p/137296658(侵權必刪)
三.演算法的基本流程
BFS經常藉助佇列來實現,佇列的特性就是FIFO(First in First out),基本的流程如下:
- 將符合要求的節點加入佇列,並把該節點標記為已遍歷狀態,防止後續造成死迴圈;
- 當佇列不為空時,從佇列中取出一個節點V
- 獲取該節點相鄰的節點並繼續放入佇列,如果當前節點等於目標節點,直接返回
四.程式碼示例
以leetcode909題目為例:
總結題意就是:從位置1到位置n的最短移動次數,梯子和蛇分別是代表要移動到對應方格。
可以看出 是求最短路徑問題,所以可以考慮安裝BFS的方式求解;
程式碼實現:
1 class Solution { 2 //轉換成一維的陣列 就是找一條路徑 就是深度優先搜尋 3 //要把對應的id轉換為對應的行和列 4 public int snakesAndLadders(int[][] board) { 5 int length = board.length; 6 boolean[] visited = new boolean[length * length + 1]; 7 Queue<int[]> que = new LinkedList<int[]>();View Code8 que.offer(new int[]{1, 0}); 9 while(!que.isEmpty()){ 10 int[] curr = que.poll(); 11 for(int i = 1; i <= 6; ++i){ 12 int nxt = curr[0] + i; 13 if(nxt > length * length){ 14 break; 15 } 16 int[] rc = id2rc(nxt, length); 17 if(board[rc[0]][rc[1]] > 0){ 18 nxt = board[rc[0]][rc[1]]; 19 } 20 if(nxt == length *length){ 21 return curr[1] + 1; 22 } 23 if(!visited[nxt]){ 24 visited[nxt] = true; 25 que.offer(new int[]{nxt, curr[1] + 1}); 26 } 27 } 28 } 29 return -1; 30 } 31 32 public int[] id2rc(int id, int n) { 33 int r = (id - 1) / n, c = (id - 1) % n; 34 if (r % 2 == 1) { 35 c = n - 1 - c; 36 } 37 return new int[]{n - 1 - r, c}; 38 } 39 }
五.leetcode相關題目(持續更新)