Clone Graph

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
/ \
\_/

这题只需一边遍历一遍复制就可以了。

因此至少可以用三种方法:

1、广度优先遍历(BFS)

2、深度优先遍历(DFS)

2.1、递归

2.2、非递归

解法一:广度优先遍历

变量说明:

映射表m用来保存原图结点与克隆结点的对应关系。

映射表visited用来记录已经访问过的原图结点,防止循环访问。

队列q用于记录广度优先遍历的层次信息。

/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(node == NULL)
return NULL;
// map from origin node to copy node
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> m;
unordered_map<UndirectedGraphNode *, bool> visited;
queue<UndirectedGraphNode*> q;
q.push(node);
while(!q.empty())
{// BFS
UndirectedGraphNode* front = q.front();
q.pop(); if(visited[front] == false)
{
visited[front] = true; UndirectedGraphNode* cur;
if(m.find(front) == m.end())
{
cur = new UndirectedGraphNode(front->label);
m[front] = cur;
}
else
{
cur = m[front];
}
for(int i = ; i < front->neighbors.size(); i ++)
{
if(m.find(front->neighbors[i]) == m.end())
{
UndirectedGraphNode* nei = new UndirectedGraphNode(front->neighbors[i]->label);
m[front->neighbors[i]] = nei;
cur->neighbors.push_back(nei); q.push(front->neighbors[i]);
}
else
{
cur->neighbors.push_back(m[front->neighbors[i]]);
}
}
}
}
return m[node];
}
};

解法二:递归深度优先遍历(DFS)

/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
map<UndirectedGraphNode *, UndirectedGraphNode *> m; UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node)
{
if(node == NULL)
return NULL; if(m.find(node) != m.end()) //if node is visited, just return the recorded nodeClone
return m[node]; UndirectedGraphNode *nodeClone = new UndirectedGraphNode(node->label);
m[node] = nodeClone;
for(int st = ; st < node->neighbors.size(); st ++)
{
UndirectedGraphNode *temp = cloneGraph(node->neighbors[st]);
if(temp != NULL)
nodeClone->neighbors.push_back(temp);
}
return nodeClone;
}
};

解法三:非递归深度优先遍历(DFS)

深度优先遍历需要进行邻居计数。如果邻居已经全部访问,则该节点访问完成,可以出栈,否则就要继续处理下一个邻居。

/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/ struct Node
{
UndirectedGraphNode *node;
int ind; //next neighbor to visit
Node(UndirectedGraphNode *n, int i): node(n), ind(i) {}
}; class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(node == NULL)
return NULL;
// map from origin node to copy node
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> m;
unordered_map<UndirectedGraphNode *, bool> visited;
stack<Node*> stk;
Node* newnode = new Node(node, );
stk.push(newnode);
visited[newnode->node] = true;
while(!stk.empty())
{// DFS
Node* top = stk.top();
UndirectedGraphNode* topCopy;
if(m.find(top->node) == m.end())
{
topCopy = new UndirectedGraphNode(top->node->label);
m[top->node] = topCopy;
}
else
topCopy = m[top->node]; if(top->ind == top->node->neighbors.size())
//finished copying its neighbors
stk.pop();
else
{
while(top->ind < top->node->neighbors.size())
{
if(m.find(top->node->neighbors[top->ind]) == m.end())
{
UndirectedGraphNode* neiCopy = new UndirectedGraphNode(top->node->neighbors[top->ind]->label);
m[top->node->neighbors[top->ind]] = neiCopy;
topCopy->neighbors.push_back(neiCopy);
if(visited[top->node->neighbors[top->ind]] == false)
{
visited[top->node->neighbors[top->ind]] = true;
Node* topnei = new Node(top->node->neighbors[top->ind], );
stk.push(topnei);
}
top->ind ++;
break;
}
else
{
topCopy->neighbors.push_back(m[top->node->neighbors[top->ind]]);
top->ind ++;
}
}
}
}
return m[node];
}
};

【LeetCode】133. Clone Graph (3 solutions)的更多相关文章

  1. 【LeetCode】133. Clone Graph 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...

  2. 【leetcode】133. Clone Graph

    题目如下: Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph con ...

  3. 【LeetCode】785. Is Graph Bipartite? 解题报告(Python)

    [LeetCode]785. Is Graph Bipartite? 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu. ...

  4. 133. Clone Graph (3 solutions)——无向无环图复制

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

  5. 【LeetCode】75. Sort Colors (3 solutions)

    Sort Colors Given an array with n objects colored red, white or blue, sort them so that objects of t ...

  6. 【LeetCode】90. Subsets II (2 solutions)

    Subsets II Given a collection of integers that might contain duplicates, S, return all possible subs ...

  7. 【Lintcode】137.Clone Graph

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

  8. 【LeetCode】207. Course Schedule (2 solutions)

    Course Schedule There are a total of n courses you have to take, labeled from 0 to n - 1. Some cours ...

  9. 【LeetCode】44. Wildcard Matching (2 solutions)

    Wildcard Matching Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any ...

随机推荐

  1. 怎样在centos安装python-mysql?

    在python中使用mysql,须要安装mysql-python依赖包, 能够通过pip来安装: pip install MySQL-python 假设错误发生,须要先安装一个开发包: yum ins ...

  2. kth-smallest-element-in-a-sorted-matrix

    //有很多讨论,比如 // https://discuss.leetcode.com/topic/52865/my-solution-using-binary-search-in-c // https ...

  3. IOS之UITabBarController

    在学习IOS开发过程中,针对于UITabBarController的使用也不少出现,UITabBarController和UINavigationController类似,UITabBarContro ...

  4. scala 学习笔记四 匿名函数

    1.介绍 Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体. 使用匿名函数后,我们的代码变得更简洁了. 下面的表达式就定义了一个接受一个Int类型输入参数的匿名函数: var ...

  5. 老三星手机i9001刷机记录

    家里的老的三星i9001,准备给我妈用,打算刷机,但又实在头疼那些复杂的刷机技术,昨天研究了一下,用比较简单的方法完成刷机,记录如下: 用卡刷比较简单,线刷不考虑 进入恢复模式的方法:1.电源+音量加 ...

  6. Immediately-Invoked Puzzler

    The Poplar Puzzle-makers weren’t too impressed. They barely noticed your simple and beautiful array ...

  7. iOS UIApplication的代理方法总结

    1.简单介绍 1> 整个应用程序的象征,一个应用程序就一个UIApplication对象.使用了单例设计模式 2> 通过[UIApplication sharedApplication]訪 ...

  8. rapidxml 序列化

    void TestRapidXml() { ]; sprintf(xmlContent,"<root><head>aaa</head><body&g ...

  9. Your Customers Do Not Mean What They Say

    Your Customers Do Not Mean What They Say Nate Jackson I'VE NEVER MET A CUSTOMER YET that wasn't all ...

  10. 利用vbs设置Java环境变量

    每次PC重装后,又要设定Java环境变量,向我这种不爱记得人,老是要去找设定内容 感觉设置环境变量还真是比较麻烦,我是希望可以做成点击一下就ok的,这样重装系统就不用那么麻烦了, 但是考虑到通用性,为 ...