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. style="visibility: hidden"和 style=“display:none”之间的区别

    style=“display:none” 隐藏页面元素: <html> <head> <script type="text/javascript"&g ...

  2. Coursera课程python中的一些程序

    Index of /code Name Last modified Size Description Parent Directory - BeautifulSoup.py 07-Aug-2015 1 ...

  3. Flask 学习(四)静态文件

    Flask 学习(四)静态文件 动态 web 应用也需要静态文件,一般是 CSS 和 JavaScript 文件.理想情况下你的服务器已经配置好提供静态文件的服务. 在开发过程中, Flask 也能做 ...

  4. 可操纵网页URL地址的js插件-url.js

    url.js是一款能够很有用方便的操纵网页URL地址的js插件.通过url.js你能够设置和获取当前URL的參数,也能够对当前URL的參数进行更新.删除操作.还能够将当前URL的參数显示为json字符 ...

  5. [Python爬虫]煎蛋网OOXX妹子图爬虫(1)——解密图片地址

    之前在鱼C论坛的时候,看到很多人都在用Python写爬虫爬煎蛋网的妹子图,当时我也写过,爬了很多的妹子图片.后来煎蛋网把妹子图的网页改进了,对图片的地址进行了加密,所以论坛里面的人经常有人问怎么请求的 ...

  6. Handler Thread 内部类引起内存泄露分析

    非静态内部类引起内存泄漏的原因 内部类的实现其实是通过编译器的语法糖(Syntactic sugar)实现的,通过生成相应的子类即以OutClassName$InteriorClassName命名的C ...

  7. 只用CSS做到完全居中

    我们都知道 margin:0 auto; 的样式能让元素水平居中,而 margin: auto; 却不能做到垂直居中……直到现在.但是,请注意!想让元素绝对居中,只需要声明元素高度,并且附加以下样式, ...

  8. GO语言基础之error

    Go错误处理 Go 语言通过内置的错误接口提供了非常简单的错误处理机制. error类型是一个接口类型,这是它的定义: type error interface { Error() string } ...

  9. [置顶] macbook 深度休眠和待机

    开发用了macbook pro, 10.8.3, 因为用windows的习惯,一直比较习惯不关机,直接休眠,不是待机standby,今天找到了一个工具,可以实现,亲测通过. 下载:https://gi ...

  10. CSDN日报20170310——《假如我是一行代码》

    [程序人生]假如我是一行代码 作者:henry-hacker 我们不止一次在生活中听到"假如我如何如何,我会如何如何"的句式.而这种句式说出来的一般意义无非就是让我们站在还有一个角 ...