作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/clone-graph/

题目描述

Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph. Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors.

Example:

Input:

{"$id":"1","neighbors":[{"$id":"2","neighbors":[{"$ref":"1"},{"$id":"3","neighbors":[{"$ref":"2"},{"$id":"4","neighbors":[{"$ref":"3"},{"$ref":"1"}],"val":4}],"val":3}],"val":2},{"$ref":"4"}],"val":1}

Explanation:
Node 1's value is 1, and it has two neighbors: Node 2 and 4.
Node 2's value is 2, and it has two neighbors: Node 1 and 3.
Node 3's value is 3, and it has two neighbors: Node 2 and 4.
Node 4's value is 4, and it has two neighbors: Node 1 and 3.

Note:

  1. The number of nodes will be between 1 and 100.
  2. The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
  3. Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
  4. You must return the copy of the given node as a reference to the cloned graph.

题目大意

完全复制一个图结构。返回新的起始节点。

解题方法

DFS

这个题和138. Copy List with Random Pointer比较类似。至于图结构,我们可以使用DFS和BFS两种结构进行遍历。

一般的遍历只需要保存是否遍历过这个节点即可,但是由于这个题需要把neighboors对应复制过来。那么需要进行改进,改进的方式是把set改成dict,保存每个老节点对应的新节点是多少。在Python中,字典直接保存对象(指针)之间的映射。所以,我们直接把遍历过的对象和复制出来的对象一一对应即可。当我们遍历到一个新的节点的时候,需要判断这个节点是否在字典中出现过,如果出现过就把它对应的复制出来的对象放到其neighboors里,若没有出现过,那么就重新构造该节点,并把原节点和该节点放到字典中保存。

Python代码如下:

"""
# Definition for a Node.
class Node(object):
def __init__(self, val, neighbors):
self.val = val
self.neighbors = neighbors
"""
class Solution(object):
def cloneGraph(self, node):
"""
:type node: Node
:rtype: Node
"""
node_copy = self.dfs(node, dict())
return node_copy def dfs(self, node, hashd):
if not node: return None
if node in hashd: return hashd[node]
node_copy = Node(node.val, [])
hashd[node] = node_copy
for n in node.neighbors:
n_copy = self.dfs(n, hashd)
if n_copy:
node_copy.neighbors.append(n_copy)
return node_copy

C++代码如下:

/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors; Node() {} Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
*/
class Solution {
public:
Node* cloneGraph(Node* node) {
if (!node) return nullptr;
if (m_.count(node))
return m_[node];
Node* node_copy = new Node(node->val, {});
m_[node] = node_copy;
for (Node* n : node->neighbors) {
node_copy->neighbors.push_back(cloneGraph(n));
}
return node_copy;
}
private:
unordered_map<Node*, Node*> m_;
};

BFS

这个题同样也可以使用BFS解决。方法也是使用了字典保存每一个对应关系。当新构造出一个节点之后,必须同时把它放到字典中保存,这个很重要。另外就是每遍历到一个节点时,都要把它的所有邻居放到队列中。

python代码如下:

"""
# Definition for a Node.
class Node(object):
def __init__(self, val, neighbors):
self.val = val
self.neighbors = neighbors
"""
class Solution(object):
def cloneGraph(self, node):
"""
:type node: Node
:rtype: Node
"""
que = collections.deque()
hashd = dict()
que.append(node)
node_copy = Node(node.val, [])
hashd[node] = node_copy
while que:
t = que.popleft()
if not t: continue
for n in t.neighbors:
if n not in hashd:
hashd[n] = Node(n.val, [])
que.append(n)
hashd[t].neighbors.append(hashd[n])
return node_copy

C++代码如下:

/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors; Node() {} Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
*/
class Solution {
public:
Node* cloneGraph(Node* node) {
queue<Node*> q;
q.push(node);
unordered_map<Node*, Node*> m_;
Node* node_copy = new Node(node->val, {});
m_[node] = node_copy;
while (!q.empty()) {
Node* t = q.front(); q.pop();
if (!t) continue;
for (Node* n : t->neighbors) {
if (!m_.count(n)) {
m_[n] = new Node(n->val, {});
q.push(n);
}
m_[t]->neighbors.push_back(m_[n]);
}
}
return node_copy;
}
};

日期

2019 年 3 月 9 日 —— 妇女节快乐

【LeetCode】133. Clone Graph 解题报告(Python & C++)的更多相关文章

  1. LeetCode: Clone Graph 解题报告

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

  2. [LeetCode] 133. Clone Graph 克隆无向图

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

  3. Java for LeetCode 133 Clone Graph

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

  4. leetcode 133. Clone Graph ----- java

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

  5. [leetcode]133. Clone Graph 克隆图

    题目 给定一个无向图的节点,克隆能克隆的一切 思路 1--2 | 3--5 以上图为例, node    neighbor 1         2, 3 2         1 3         1 ...

  6. Leetcode#133 Clone Graph

    原题地址 方法I,DFS 一边遍历一边复制 借助辅助map保存已经复制好了的节点 对于原图中每个节点,如果已经复制过了,直接返回新节点的地址,如果没复制过,则复制并加入map中,接着依次递归复制其兄弟 ...

  7. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  8. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  9. 133. Clone Graph 138. Copy List with Random Pointer 拷贝图和链表

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

随机推荐

  1. 富集分析DAVID、Metascape、Enrichr、ClueGO

    前言 一般我们挑出一堆感兴趣的基因想临时看看它们的功能,需要做个富集分析.虽然公司买了最新版的数据库,如KEGG,但在集群跑下来嫌麻烦.这时网页在线或者本地化工具派上用场了. DAVID DAVID地 ...

  2. Docker 外部访问容器Pp、数据管理volume、网络network 介绍

    Docker 外部访问容器Pp.数据管理volume.网络network 介绍 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来 指定端口映射. ...

  3. mysql order by 多个字段排序实现组内排序

    总结:大组在前,小组在后,计量值再最后,即可实现组内排序:下边是参考别人的具体实例: 工作中需用到order by 后两个字段排序,但结果却产生了一个Bug,以此备录. [1]复现问题场景 为了说明问 ...

  4. 类成员函数调用delete this会发生什么呢?

    有如下代码 class myClass { public: myClass(){}; ~myClass(){}; void foo() { delete this; } }; int main() { ...

  5. matplotlib以对象方式绘制子图

    matplotlib有两种绘图方式,一种是基于脚本的方式,另一种是面向对象的方式 面向脚本的方式类似于matlab,面向对象的方式使用起来更为简便 创建子图的方式也很简单 fig,ax = plt.s ...

  6. 论文解读(SDNE)《Structural Deep Network Embedding》

    论文题目:<Structural Deep Network Embedding>发表时间:  KDD 2016 论文作者:  Aditya Grover;Aditya Grover; Ju ...

  7. Java项目发现==顺手改成equals之后,会发生什么?

    最近发生一件很尴尬的事情,在维护一个 Java 项目的时候,发现有使用 == 来比较两个对象的属性, 于是顺手就把 == 改成了 equals.悲剧发生...... == 和 equals 的区别 = ...

  8. 学习java 7.5

    学习内容: Alt + Insert 快捷键 根据需要选择操作 继承的格式 public class 子类名 extends 父类名{} 继承好处:提高了代码的复用性,维护性 弊端:改变父类,子类也改 ...

  9. Zookeeper之创建组,加入组,列出组成员和删除组

    public class CreateGroup implements Watcher { private static final int SESSION_TIMEOUT=5000; //ZooKe ...

  10. Can namespaces be nested in C++?

    In C++, namespaces can be nested, and resolution of namespace variables is hierarchical. For example ...