BFS基礎css
廣度優先搜索(Breadth First Search)用於按離始節點距離、由近到遠漸次訪問圖的節點,可視化BFShtml
一般使用隊列(queue)結構模擬BFS過程,關於queue見:算法與數據結構基礎 - 隊列(Queue)git
最直觀的BFS應用是圖和樹的遍歷,其中圖經常使用鄰接表或矩陣表示,例如 LeetCode題目 690. Employee Importance:github
// LeetCode 690. Employee Importance
/* class Employee { public: int id; int importance; vector<int> subordinates; }; */
// Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1 Output: 11 class Solution { public: int getImportance(vector<Employee*> employees, int id) { int res=0; unordered_map<int,Employee*> m; for(Employee* e:employees) m[e->id]=e; queue<Employee*> q; q.push(m[id]); while(!q.empty()){ Employee* cur=q.front();q.pop(); res+=cur->importance; for(auto s:cur->subordinates) q.push(m[s]); } return res; } };
相關LeetCode題:算法
690. Employee Importance 題解數據結構
513. Find Bottom Left Tree Value 題解ide
拓撲排序(Topological Sort)也應用了BFS遍歷思想、以達成按依賴關係排序的目的,關於拓撲排序見:算法與數據結構基礎 - 拓撲排序(Topological Sort)
層信息
BFS思路是從某節點層層往外擴展,一些場景下咱們須要處理層(level)相關的信息,例如 LeetCode題目 102. Binary Tree Level Order Traversal:
class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> res; if(root==NULL) return res; queue<TreeNode*> q; q.push(root); while(!q.empty()){ int size=q.size(); vector<int> tmp; for(int i=0;i<size;i++){ //處理當前level TreeNode* cur=q.front();q.pop(); tmp.push_back(cur->val); if(cur->left) q.push(cur->left); if(cur->right) q.push(cur->right); } res.push_back(tmp); } return res; } };
以上代碼不單遍歷了樹節點,還加了按層(level)處理,注意以上代碼與遍歷代碼的細微差異。
相關LeetCode題:
102. Binary Tree Level Order Traversal 題解
429. N-ary Tree Level Order Traversal 題解
111. Minimum Depth of Binary Tree 題解
993. Cousins in Binary Tree 題解
515. Find Largest Value in Each Tree Row 題解
最短距離
BFS另外一個重要的應用就是求最短路徑,能夠是單點到單點、單點到多點、多點到多點之間的路徑。
當問題出現最小(minimum)、最短(shortest)等字樣時可考慮用BFS求解,通常求解思路是 1/找出知足條件的起始點,2/由起始點開始進行BFS,3/遇到終點結束。
相關LeetCode題:
以上例題路徑之間沒有差異,更復雜的一種狀況是路徑具有權重。對有權圖求解最短路徑,通常狀況下會想到Bellman-Ford、Dijkstra算法,而BFS思想是這些算法思想的核心。
相關LeetCode題:
因問題不一樣、訪問臨近節點的方式各異,在使用BFS時咱們可能會遇到重複訪問某一節點的狀況。
爲了不重複訪問節點形成死循環,經常使用hashtable來記錄節點是否已經被訪問。
相關LeetCode題: