算法與數據結構基礎 - 廣度優先搜索(BFS)


BFS基礎

廣度優先搜索(Breadth First Search)用於按離始節點距離、由近到遠漸次訪問圖的節點,可視化BFS

通常使用隊列(queue)結構模擬BFS過程,關於queue見:算法與數據結構基礎 - 隊列(Queue)

 

最直觀的BFS應用是圖和樹的遍歷,其中圖常用鄰接表或矩陣表示,例如 LeetCode題目 690. Employee Importance:

// 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  題解

101. Symmetric Tree  題解

529. Minesweeper  題解

133. Clone Graph  題解

 

拓撲排序(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題:

994. Rotting Oranges  題解

127. Word Ladder  題解

286. Walls and Gates  題解

505. The Maze II  題解

815. Bus Routes  題解

854. K-Similar Strings  題解

 

以上例題路徑之間沒有差別,更復雜的一種情況是路徑具備權重。對有權圖求解最短路徑,一般情況下會想到Bellman-Ford、Dijkstra算法,而BFS思想是這些算法思想的核心。

 

相關LeetCode題:

 

避免BFS死循環

因問題不同、訪問臨近節點的方式各異,在使用BFS時我們可能會遇到重復訪問某一節點的情況。

為了避免重復訪問節點造成死循環,常用hashtable來記錄節點是否已經被訪問。

 

相關LeetCode題:

490. The Maze  題解

864. Shortest Path to Get All Keys   題解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM