作者: 负雪明烛
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:

  1. Input:
  2. {"$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}
  3. Explanation:
  4. Node 1's value is 1, and it has two neighbors: Node 2 and 4.
  5. Node 2's value is 2, and it has two neighbors: Node 1 and 3.
  6. Node 3's value is 3, and it has two neighbors: Node 2 and 4.
  7. 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代码如下:

  1. """
  2. # Definition for a Node.
  3. class Node(object):
  4. def __init__(self, val, neighbors):
  5. self.val = val
  6. self.neighbors = neighbors
  7. """
  8. class Solution(object):
  9. def cloneGraph(self, node):
  10. """
  11. :type node: Node
  12. :rtype: Node
  13. """
  14. node_copy = self.dfs(node, dict())
  15. return node_copy
  16. def dfs(self, node, hashd):
  17. if not node: return None
  18. if node in hashd: return hashd[node]
  19. node_copy = Node(node.val, [])
  20. hashd[node] = node_copy
  21. for n in node.neighbors:
  22. n_copy = self.dfs(n, hashd)
  23. if n_copy:
  24. node_copy.neighbors.append(n_copy)
  25. return node_copy

C++代码如下:

  1. /*
  2. // Definition for a Node.
  3. class Node {
  4. public:
  5. int val;
  6. vector<Node*> neighbors;
  7. Node() {}
  8. Node(int _val, vector<Node*> _neighbors) {
  9. val = _val;
  10. neighbors = _neighbors;
  11. }
  12. };
  13. */
  14. class Solution {
  15. public:
  16. Node* cloneGraph(Node* node) {
  17. if (!node) return nullptr;
  18. if (m_.count(node))
  19. return m_[node];
  20. Node* node_copy = new Node(node->val, {});
  21. m_[node] = node_copy;
  22. for (Node* n : node->neighbors) {
  23. node_copy->neighbors.push_back(cloneGraph(n));
  24. }
  25. return node_copy;
  26. }
  27. private:
  28. unordered_map<Node*, Node*> m_;
  29. };

BFS

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

python代码如下:

  1. """
  2. # Definition for a Node.
  3. class Node(object):
  4. def __init__(self, val, neighbors):
  5. self.val = val
  6. self.neighbors = neighbors
  7. """
  8. class Solution(object):
  9. def cloneGraph(self, node):
  10. """
  11. :type node: Node
  12. :rtype: Node
  13. """
  14. que = collections.deque()
  15. hashd = dict()
  16. que.append(node)
  17. node_copy = Node(node.val, [])
  18. hashd[node] = node_copy
  19. while que:
  20. t = que.popleft()
  21. if not t: continue
  22. for n in t.neighbors:
  23. if n not in hashd:
  24. hashd[n] = Node(n.val, [])
  25. que.append(n)
  26. hashd[t].neighbors.append(hashd[n])
  27. return node_copy

C++代码如下:

  1. /*
  2. // Definition for a Node.
  3. class Node {
  4. public:
  5. int val;
  6. vector<Node*> neighbors;
  7. Node() {}
  8. Node(int _val, vector<Node*> _neighbors) {
  9. val = _val;
  10. neighbors = _neighbors;
  11. }
  12. };
  13. */
  14. class Solution {
  15. public:
  16. Node* cloneGraph(Node* node) {
  17. queue<Node*> q;
  18. q.push(node);
  19. unordered_map<Node*, Node*> m_;
  20. Node* node_copy = new Node(node->val, {});
  21. m_[node] = node_copy;
  22. while (!q.empty()) {
  23. Node* t = q.front(); q.pop();
  24. if (!t) continue;
  25. for (Node* n : t->neighbors) {
  26. if (!m_.count(n)) {
  27. m_[n] = new Node(n->val, {});
  28. q.push(n);
  29. }
  30. m_[t]->neighbors.push_back(m_[n]);
  31. }
  32. }
  33. return node_copy;
  34. }
  35. };

日期

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. R语言与医学统计图形-【20】ggplot2图例

    ggplot2绘图系统--图例:guide函数.标度函数.overrides.aes参数 图例调整函数guide_legend也属于标度函数,但不能单独作为对象使用,即不能如p+guide_legen ...

  2. c#年份筛选

    年份: <script type="text/javascript" src="http://www.shicishu.com/down/WdatePicker.j ...

  3. 华为AppTouch携手全球运营商,助力开发者出海

    内容来源:华为开发者大会2021 HMS Core 6 APP services技术论坛,主题演讲<华为AppTouch携手全球运营商,助力开发者出海>. 演讲嘉宾:华为消费者云服务App ...

  4. 巩固javaweb第十六天

    巩固内容: 下拉框 在注册功能中,地区的选择使用了下拉框,可以从地区选项中选择一个地区.在这个 例子中,只允许选择一个,而在有些情况下,下拉框可以进行多选.所以,从功能上来说, 下拉框具有单选按钮和复 ...

  5. Shell 格式化输出printf、awk

    目录 Shell 文件的格式化与相关处理 printf.awk 格式化打印printf 案例.格式化输出文件内容 输出命令echo 案例 awk数据处理工具 语法格式 处理流程 AWK内置变量 条件 ...

  6. 零基础学习java------36---------xml,MyBatis,入门程序,CURD练习(#{}和${}区别,模糊查询,添加本地约束文件) 全局配置文件中常用属性 动态Sql(掌握)

    一. xml  1. 文档的声明 2. 文档的约束,规定了当前文件中有的标签(属性),并且规定了标签层级关系 其叫html文档而言,语法要求更严格,标签成对出现(不是的话会报错) 3. 作用:数据格式 ...

  7. RB-Tree深度探索

    关联式容器就是通过key值来寻找value,这个和数据库很相像,为了提升查找效率,因此关联式容器底层大多数用红黑树或哈希表来实现. 红黑树是高度平衡的二叉树,它也被称为平衡二元搜索树. 如上所示,正常 ...

  8. 03-Collection用例管理及批量执行

    当我们对一个或多个系统中的很多用例进行维护时,首先想到的就是对用例进行分类管理,同时还希望对这批用例做回归测试 .在postman也提供了这样一个功能,就是Collection .通过这个Collec ...

  9. RTTI (Run-time type information) in C++

    In C++, RTTI (Run-time type information) is available only for the classes which have at least one v ...

  10. LR中的快捷建

    Ctrl+F  弹出搜索对话框 CTRL+F8  弹出view tree 界面 (寻找关联) 觉得不错的可关注微信公众号在手机上观看,让你用手机边玩边看