9. Breath First Search(with problem example)

0. Basic Concepts

0.1 When to use BFS?

  1. Traversal in Graph

    • Level Order Traversal
    • Connected Component
    • Topological Sorting
  2. Shortest Path in Simple Graph
    Limited to the simple graph, which means no direction, edge length is 1.

1. Problem Type:

Tips:

  1. Use Hash Map/Set wisely
  2. If we could use BFS, avoid using DFS. It’s more clear and easy.

1.1 Level Traverse in Binary Tree

Specific content was mentioned in 4.Binary Tree(With sample problem).

1.2 HashMap

In some problem, we hash map/set is good tool for us to solve the problem. For example, if we want to check there is a circle in graph.

Also, classic clone graph problem as second example here. We will use hash map to store the relation between the old node and new node.

1.2.1 Examples:

178. Graph Valid Tree

Solve the problem by using unordered_set and queue. The main idea is BFS, each time we visit a new node, put it into vectice and queue.

bool validTree(int n, vector<pair<int, int>>& edges) {
   
        vector<unordered_set<int>> g(n, unordered_set<int>());
        unordered_set<int> v;
        queue<int> q;
        q.push(0);
        v.insert(0);
        for (auto a : edges) {
   
            g[a.first].insert(a.second);
            g[a.second].insert(a.first);
        }
        while (!q.empty()) {
   
            int t = q.front(); q.pop();
            for (auto a : g[t]) {
   
                if (v.find(a) != v.end()) return false;
                v.insert(a);
                q.push(a);
                g[a].erase(t);
            }
        }
        return v.size() == n;
    }

137. Clone Graph

As the problem required, we need to deep copy the graph. Thus, we will use queue to bfs the graph, and hash map to store the relation between old node and new node.

Two solution below, but the same idea here.

Solution1:

  1. BFS the graph, meanwhile, copy the node and store into hashmap.
  2. Iterate the original nodes set, fill up the neighbors
UndirectedGraphNode* cloneGraph(UndirectedGraphNode* node) {
   
        // write your code here
        if(!node)
            return node;
        unordered_map<int, UndirectedGraphNode* > hash;
        
        queue<UndirectedGraphNode*> Q;
        unordered_set<UndirectedGraphNode*> set;
        set.insert(node);
        Q.push(node);
        
        while(! Q.empty())
        {
   
            UndirectedGraphNode* ptr = Q.front(); Q.pop();
            if(hash.find(ptr->label) == hash.end())
            {
   
                UndirectedGraphNode* tmp = new UndirectedGraphNode(ptr->label);
                hash[ptr->label] = tmp;
            }
                
            
            for(auto now : ptr->neighbors)
            {
   
                if(set.find(now) == set.end())
                {
   
                    set.insert(now);
                    Q.push(now);
                }
            }
        }
        
        for(auto now : set)
        {
   
            UndirectedGraphNode* ptr = hash[now->label];
            for(auto neighbor : now->neighbors)
            {
   
                ptr->neighbors.push_back(hash[neighbor->label]);
            }
        }
        return hash[node->label];
        
    }

Solution2:

  1. Use hash map to store the old node and new node. Every time it visits a new node, fill its neighbors immediately.

    UndirectedGraphNode* cloneGraph(UndirectedGraphNode* node) {
   
        // write your code here
        if(!node){
   
            return node;
        }
        
        // initialization
        UndirectedGraphNode* p1 = node;
        UndirectedGraphNode* p2 = new UndirectedGraphNode(node ->label);
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> old2new;
        queue<UndirectedGraphNode*> queue;
        
        // queue used to record the orginal node
        queue.push(node);
        
        // old2new is a hash to record the connection of old node and new one
        old2new[node] = p2;
        
        // while there existed nodes remained to be visited
        while(! queue.empty()){
   
            p1 = queue.front(); p2 = old2new[p1];
            queue.pop();
            
            vector<UndirectedGraphNode *> neighbors = p1->neighbors;
            for(int i = 0; i < neighbors.size(); i++){
   
                // if neighbor node is new node
                if(old2new.find(neighbors[i]) == old2new.end()){
   
                    UndirectedGraphNode* tmp = new UndirectedGraphNode(neighbors[i]->label);
                    old2new[neighbors[i]] = tmp;
                    p2->neighbors.push_back(tmp)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值