Leetcode---Clone Graph

这道题可以用DFS和BFS分别完成。

要说DFS和BFS讲的透彻的,还是算法导论,下面给出算法导论上的伪代码,注意,其中任何一行code都是非常值得玩味的:

BFS伪代码

BFS(G, s)
 1  for each vertex u ∈ V [G] - {s}
 2       do color[u] ← WHITE
 3          d[u] ← ∞
 4          π[u] ← NIL
 5  color[s] ← GRAY
 6  d[s] ← 0 
 7  π[s] ← NIL 
 8  Q ← Ø
 9  ENQUEUE(Q, s)
10  while Q ≠ Ø
11      do u ← DEQUEUE(Q) 
12         for each v ∈ Adj[u] 
13             do if color[v] = WHITE
14                   then color[v] ← GRAY
15                        d[v] ← d[u] + 1
16                        π[v] ← u 
17                        ENQUEUE(Q, v)
18         color[u] ← BLACK

当图中有环的时候,可能出现重复访问的情况,这时用color着色,防止重复访问已经访问过的节点。其实关键是Gray和White,Black就是标记这个节点是不是完全被访问完成了。

注意,之前访问过的节点根本不能进入队列。

DFS伪代码

DFS(G)
1  for each vertex u ∈ V [G]
2       do color[u] ← WHITE
3          π[u] ← NIL
4  time ← 0
5  for each vertex u ∈ V [G]
6       do if color[u] = WHITE
7             then DFS-VISIT(u)
DFS-VISIT(u)
1  color[u] ← GRAY
2  time ← time +1
3  d[u] <-time
4  for each v ∈ Adj[u]
5       do if color[v] = WHITE
6             then π[v] ← u
7                         DFS-VISIT(v)
8  color[u] <-BLACK
9  f [u] ▹ time ← time +1

注意,也用着色来避免重复访问,关键也是Gray和White。当一个节点之前被访问过的情况下,无法递归调用DFS-VISIT。

另外,我们平时在写DFS的时候,尽量脑子只思考两层,第一层for循环,第二层递归,否则很容易晕。


BFS代码:

unordered_map<UndirectedGraphNode*,UndirectedGraphNode *> mp;
unordered_map<UndirectedGraphNode*,bool> color;
UndirectedGraphNode * bfs(UndirectedGraphNode *node){
    if(node==NULL)
        return NULL;
    UndirectedGraphNode * root=new UndirectedGraphNode(node->label);
    mp[node]=root;
    queue<UndirectedGraphNode *> Q;
    Q.push(node);
    color[node]=true;
    while(!Q.empty()){
        UndirectedGraphNode * front=Q.front();
        Q.pop();
        for(int i=0;i<front->neighbors.size();i++){
            if(color[front->neighbors[i]]!=true){
                Q.push(front->neighbors[i]);
                color[front->neighbors[i]]=true;
                UndirectedGraphNode * temp=new UndirectedGraphNode(front->neighbors[i]->label);
                mp[front->neighbors[i]]=temp;
                mp[front]->neighbors.push_back(temp);
            }
            else{
                mp[front]->neighbors.push_back(mp[front->neighbors[i]]);
            }
        }
    }
    return root;
}

UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
    return bfs(node);
}

DFS代码:

unordered_map<UndirectedGraphNode*,UndirectedGraphNode *> mp;
unordered_map<UndirectedGraphNode*,bool> color;
UndirectedGraphNode * dfs(UndirectedGraphNode *node,UndirectedGraphNode *parent){
    if(node==NULL)
        return NULL;
    UndirectedGraphNode * me=NULL;
    color[node]=true;
    if(mp[node]==0){
        me=new UndirectedGraphNode(node->label);
        mp[node]=me;

    }
    else{
        me=mp[node];

    }
    if(parent!=NULL)
        parent->neighbors.push_back(me);
    for(int i=0;i<node->neighbors.size();i++){
        if(color[node->neighbors[i]]==true)
            me->neighbors.push_back(mp[node->neighbors[i]]);
        if(color[node->neighbors[i]]!=true)
            dfs(node->neighbors[i],me);
    }

    return me;
}

UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
    return dfs(node,NULL);
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值