133. Clone Graph

题目描述

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
OJs undirected graph serialization:Nodes are labeled uniquely.

We use # as a separator for each node, and,as a separator for node label and each neighbor of the node.As an example, consider the serialized graph{0,1,2# 1,2# 2,2}.The graph has a total of three nodes, and therefore contains three parts as separated by#.First node is labeled as0. Connect node0to both nodes1and2.Second node is labeled as1. Connect node1to node2.Third node is labeled as2. Connect node2to node2(itself), thus forming a self-cycle.
Visually, the graph looks like the following:

   1
  / \
 /   \
0 --- 2
     / \
     \_/

给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆)。图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node])。
提示:
节点数介于 1 到 100 之间。
无向图是一个简单图,这意味着图中没有重复的边,也没有自环。
由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q
也必须是节点 p 的邻居。
必须将给定节点的拷贝作为对克隆图的引用返回。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> neighbors;

    Node() {}

    Node(int _val, vector<Node*> _neighbors) {
        val = _val;
        neighbors = _neighbors;
    }
};
*/

方法1

DFS
遍历一定是完备的,一定会访问到每一个节点,不会遗漏。

class Solution {
public:
    Node* cloneGraph(Node* node) {

        if(!node)
        	return nullptr;
        if(m.find(node)!=m.end())
        	return m[node];
        Node *root = new Node(node->val,{});
        m[node] = root;
        for(Node* neighbor : node->neighbors) 
        {
        	(root->neighbors).push_back(cloneGraph(neighbor));
        }
       
        return root;
    }
private:  
    //不同于BFS,这里的DFS中的m以及程序顺序的流程逻辑,确保
    //节点的连接关系只会出现在第一次复制节点处,因此并不会出现
    //重复连接的情况                         
    unordered_map<Node*, Node*> m;
};                                

方法2

BFS,这个更容易理解一些,可以想象有左右两个图,左图是原图,右图是复制图。可以看做刚开始两个图一个节点都没有,我们是一个节点一个节点地逐渐增加,从无到有,映射m保存是原节点所对应的复制节点,我们增加节点是根据邻接关系加,而对应的邻接关系只需要在对应的复制图上照原样重复即可,对于BFS,扩展节点时确定邻接关系

class Solution {
public:
    Node* cloneGraph(Node* node) {

    	if(!node)
            return nullptr;
        unordered_map<Node*, Node*> m;
        Node* root = new Node(node->val,{});
        m[node] = root;//表示现在左右两图只有根节点一个节点
        queue<Node*> q;
        q.push(node);
        while(!q.empty())   
        {
            Node* cur = q.front();
            q.pop();

            for(auto neighbor : cur->neighbors) 
            {
                if(m.find(neighbor) == m.end()) 
                {
                    //在图上增加这个节点
                    m[neighbor] = new Node(neighbor->val,{});
                    q.push(neighbor);
                }
                //将原图节点的邻接对应关系在对应的复制节点上
                //照原样重复一遍
                (m[cur]->neighbors).push_back(m[neighbor]);
            }
        }
        return root;
    }
};

posted on 2021-05-16 10:43  朴素贝叶斯  阅读(38)  评论(0编辑  收藏  举报

导航