1. 程式人生 > 其它 >廣度優先搜尋(BFS)理解

廣度優先搜尋(BFS)理解

一.基本概念

廣度優先搜尋就是一種通過逐層遍歷所有訪問隊形,從而找到通過最短節點數到達目標的演算法。、

主要用於解決在一個無加權圖下找到從起點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[]>();
8 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 }
View Code

五.leetcode相關題目(持續更新)

815. 公交路線

773. 滑動謎題