LeetCode133:Clone Graph

mickole發表於2014-02-19

題目:

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ's 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 #.

  1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
  2. Second node is labeled as 1. Connect node 1 to node 2.
  3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

Visually, the graph looks like the following:

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

解題思路:

本題要解決的問題就是對一個圖進行clone,這不禁讓我們想起圖的遍歷:DFS和BFS,所以我們可以再遍歷圖中某個點時,增加一些附加的操作而不僅僅是訪問它,這裡我們要增加的附加操作即對該點進行clone。
現在我們利用DFS和BFS兩種方式進行解題。

實現程式碼:

#include <iostream>
#include <vector>
#include <queue> 
#include <unordered_map>
using namespace std;

/*
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.


OJ's 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 as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:

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

*/

struct UndirectedGraphNode {
     int label;
     vector<UndirectedGraphNode *> neighbors;
     UndirectedGraphNode(int x) : label(x) {};
};

class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if(node == NULL)
            return NULL;
        unordered_map<int, UndirectedGraphNode*> hashtable;//標誌位,是否已拷貝了key為label,value為新拷貝的node 
        return dfsclone(node, hashtable);
        
    }
    
    //DFS 
    UndirectedGraphNode *dfsclone(UndirectedGraphNode *node, unordered_map<int, UndirectedGraphNode*> &hashtable)
    {
        if(node == NULL)
            return NULL;
        if(hashtable.count(node->label) > 0)
            return hashtable[node->label];//已經拷貝好了,則直接返回即可,否則進行下面的拷貝操作 
        UndirectedGraphNode *copyNode = new UndirectedGraphNode(node->label);
        hashtable[copyNode->label] = copyNode;
        vector<UndirectedGraphNode *>::iterator iter;
        for(iter = node->neighbors.begin(); iter != node->neighbors.end(); ++iter)
        {
            copyNode->neighbors.push_back(dfsclone(*iter, hashtable));//進行深度優先演算法拷貝 
        }
        
        return copyNode;
    }
    
        //BFS 
    UndirectedGraphNode *bfsclone(UndirectedGraphNode *node, unordered_map<int, UndirectedGraphNode*> &hashtable)
    {
        if(node == NULL)
            return NULL;
        queue<UndirectedGraphNode *> qu;
        UndirectedGraphNode *copyNode = new UndirectedGraphNode(node->label);
        hashtable[copyNode->label] = copyNode;
        qu.push(node);
        while(!qu.empty())
        {
            UndirectedGraphNode *tnode = qu.front();
            qu.pop();
            vector<UndirectedGraphNode *>::iterator iter;
            for(iter = node->neighbors.begin(); iter != node->neighbors.end(); ++iter)
            {
                if(hashtable.count((*iter)->label) == 0)
                {
                    UndirectedGraphNode *tnode = new UndirectedGraphNode((*iter)->label);
                    hashtable[(*iter)->label] = tnode;
                    qu.push(*iter);
                }
                (hashtable[tnode->label])->neighbors.push_back(hashtable[(*iter)->label]);
                     
            }
            
        }        
        return copyNode;
    }
};
int main(void)
{
    return 0;
}

相關文章