DFS與BFS的原理 簡單易懂 力扣例題

2021-10-24 03:37:06 字數 2019 閱讀 8645

dfs:

思想:一直往深處走,直到找到解或者走不下去為止;

使用棧儲存未被檢測的結點。結點按照深度優先的次序被訪問並依次被壓入棧中,並以相反的次序出棧進行新的檢測。類似於樹的先根遍歷。例如:走迷宮,你沒有辦法用分身術來站在每個走過的位置,不撞南山不回頭。

使用dfs解決問題時最先想到的應該是遞迴和棧(stack)

dfs是從起始頂點開始,遞迴訪問其所有鄰近節點,比如a節點是其第乙個鄰近節點,而b節點又是a的乙個鄰近節點,則dfs訪問a節點後再訪問b節點,如果b節點有未訪問的鄰近節點的話將繼續訪問其鄰近節點,否則繼續訪問a的未訪問鄰近節點,當所有從a節點出去的路徑都訪問完之後,繼續遞迴訪問除a以外未被訪問的鄰近節點。

bfs:

使用佇列儲存未被檢測的節點,結點按照寬度優先的次序被訪問和進出佇列,類似於樹的按層次遍歷的過程,例如:你的眼鏡掉在地上,你趴在地板上找,你總是先**最接近你的地方,如果沒有,你再摸遠一點的地方。

如圖:

可以看出是一層一層的遍歷,在使用bfs解決問題的時候最先想到的方式是佇列(queue,fifo)

其主要思想是從起始點開始,將其鄰近的所有頂點都加到乙個佇列(fifo)中去,然後標記下這些頂點離起始頂點的距離為1.最後將起始頂點標記為已訪問,今後就不會再訪問。然後再從佇列中取出最先進隊的頂點a,也取出其周邊鄰近節點,加入佇列末尾,最後離開這個頂點a。依次下去,直到隊列為空為止。從上面描述的過程我們知道每個頂點被訪問的次數最多一次(已訪問的節點不會再訪問)

例題:鑰匙和房間

**於在形式上,對於每個房間 i 都有乙個鑰匙列表 rooms[i],每個鑰匙 rooms[i][j] 由 [0,1,…,n-1] 中的乙個整數表示,其中 n = rooms.length。 鑰匙 rooms[i][j] = v 可以開啟編號為 v 的房間。

最初,除 0 號房間外的其餘所有房間都被鎖住。

你可以自由地在房間之間來回走動。

如果能進入每個房間返回 true,否則返回 false。

示例 1:

輸入: [[1],[2],[3],]

輸出: true

解釋:我們從 0 號房間開始,拿到鑰匙 1。

之後我們去 1 號房間,拿到鑰匙 2。

然後我們去 2 號房間,拿到鑰匙 3。

最後我們去了 3 號房間。

由於我們能夠進入每個房間,我們返回 true。

示例 2:

1 <= rooms.length <= 1000

0 <= rooms[i].length <= 1000

所有房間中的鑰匙數量總計不超過 3000

深度搜尋解法:

遍歷整張圖,統計可以到達的節點個數,並利用陣列vis標記當前節點是否訪問過,以防止重複訪問。

class

solution

public

void

dfs(list

> rooms,

int x)}}

}

廣度優先搜尋解法:

遍歷整張圖,統計可以到達的節點個數,並利用陣列 \textitvis 標記當前節點是否訪問過,以防止重複訪問

class

solution}}

return num == n;

}}

que.offer(it);}}

}return num == n;

}

簡單易懂的BFS

bfs從起點開始,優先搜尋離起點最近的點,然後由這個最近的點擴充套件其他稍近的點,這樣一層一層的擴充套件,就像水波擴散一樣。bfs需要借助佇列來實現 初始的時候把起始點放入佇列中,並標記起點訪問 如果佇列不為空,從佇列中取出乙個元素x,否則演算法結束 訪問和x相連的所有點v,如果v沒有被訪問,把v入...

力扣分模組練習 DFS與BFS

題意 給定乙個包含了一些 0 和 1 的非空二維陣列 grid 乙個 島嶼 是由一些相鄰的 1 代表土地 構成的組合,這裡的 相鄰 要求兩個 1 必須在水平或者豎直方向上相鄰。你可以假設 grid 的四個邊緣都被 0 代表水 包圍著。找到給定的二維陣列中最大的島嶼面積。如果沒有島嶼,則返回面積為 0...

DFS與BFS的應用

題目 給出乙個n m矩陣,矩陣中的元素為0或1,稱位置 x,y 與其上下左右四個位置 x,y 1 x,y 1 x 1,y x 1,y 是相鄰的。如果矩陣中有若干個1是相鄰的 不必兩兩相鄰 那麼稱這些1構成了乙個 塊 求給定的矩陣中 塊 的個數。如 0 1 1 1 0 0 1 0 0 1 0 0 0 ...