[leetcod] 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/ \\_/


题解:
引用:http://www.cnblogs.com/springfor/p/3874591.html
这道题考察对图的遍历和利用HashMap拷贝的方法。
对图的遍历就是两个经典的方法DFS和BFS。BFS经常用Queue实现,DFS经常用递归实现(可改为栈实现)。
拷贝方法是用用HashMap,key存原始值,value存copy的值,用DFS,BFS方法遍历帮助拷贝neighbors的值。

先复习下DFS和BFS。

DFS(Dpeth-first Search)
顾名思义,就是深度搜索,一条路走到黑,再选新的路。
记得上Algorithm的时候,教授举得例子就是说,DFS很像好奇的小孩,你给这个小孩几个盒子套盒子,好奇的小孩肯定会一个盒子打开后继续再在这个盒子里面搜索。
等把这一套盒子都打开完,再打开第二套的。
Wikipedia上的讲解是:“Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures.
One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible
along each branch before backtracking.”
通常来说简便的DFS写法是用递归,如果非递归的话就是栈套迭代,思想是一样的。
递归写法的DFS伪代码如下:
Input: A graph G and a root v of G
1   procedure DFS(G,v):
2       label v as discovered
3       for all edges from v to w in G.adjacentEdges(v) do
4           if vertex w is not labeled as discovered then
5               recursively call DFS(G,w)
非递归写法的DFS伪代码如下:
Input: A graph G and a root v of G
复制代码
1   procedure DFS-iterative(G,v):
2       let S be a stack
3       S.push(v)
4       while S is not empty
5             v ← S.pop() 
6             if v is not labeled as discovered:
7                 label v as discovered
8                 for all edges from v to w in G.adjacentEdges(v) do
9                     S.push(w)
复制代码



BFS(Breadth-first Search)
这个就是相对于BFS的另外一种对图的遍历方法,对于一个节点来说先把所有neighbors都检查一遍,再从第一个neighbor开始,循环往复。
由于BFS的这个特质,BFS可以帮助寻找最短路径。
Wikipedia上面对BFS的定义是:
“In graph theory, breadth-first search (BFS) is a strategy for searching in a graphwhen search is limited to essentially two operations: (a) visit and inspect a node of a graph; (b) gain access to visit the nodes that neighbor the currently visited node. The BFS begins at a root node and inspects all the neighboring nodes. Then for each of those neighbor nodes in turn, it inspects their neighbor nodes which were unvisited, and so on. Compare BFS with the equivalent, but more memory-efficient
Iterative deepening depth-first search and contrast with depth-first search.”

通常BFS用queue+循环实现,伪代码如下:
Input: A graph G and a root v of G
复制代码
1   procedure BFS(G,v) is
 2       create a queue Q
 3       create a set V
 4       add v to V
 5       enqueue v onto Q
 6       while Q is not empty loop
 7          t ← Q.dequeue()
 8          if t is what we are looking for then
 9             return t
10         end if
11         for all edges e in G.adjacentEdges(t) loop
12            u ← G.adjacentVertex(t,e)
13            if u is not in V then
14                add u to V
15                enqueue u onto Q
16            end if
17         end loop
18      end loop
19      return none
20  end BFS
复制代码
********************************************************************************************************************************
下面就是这道题的3种解题方法。

第一种实现方法是BFS的,就是先将头节点入queue,每一次queue出列一个node,然后检查这个node的所有的neighbors,如果没visited过,就入队,并更新neighbor。
然后更新新的neighbor列表。
代码如下:
复制代码
1     public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         if(node == null)
 3             return null;
 4             
 5         HashMap<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
 6         LinkedList<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
 7         UndirectedGraphNode head = new UndirectedGraphNode(node.label);
 8         hm.put(node, head);
 9         queue.add(node);
10         
11         while(!queue.isEmpty()){
12             UndirectedGraphNode curnode = queue.poll();
13             for(UndirectedGraphNode aneighbor: curnode.neighbors){//check each neighbor
14                 if(!hm.containsKey(aneighbor)){//if not visited,then add to queue
15                     queue.add(aneighbor);
16                     UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
17                     hm.put(aneighbor, newneighbor);
18                 }
19                 
20                 hm.get(curnode).neighbors.add(hm.get(aneighbor));
21             }
22         }
23         
24         return head;
25     }
复制代码
DFS的递归操作如下,迭代复制neighbors:
复制代码
1     public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         if(node == null)
 3             return null;
 4             
 5         HashMap<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
 6         UndirectedGraphNode head = new UndirectedGraphNode(node.label);
 7         hm.put(node, head);
 8         
 9         DFS(hm, node);//DFS
10         return head;
11     }
12     public void DFS(HashMap<UndirectedGraphNode, UndirectedGraphNode> hm, UndirectedGraphNode node){
13         if(node == null)
14             return;
15             
16         for(UndirectedGraphNode aneighbor: node.neighbors){ 
17             if(!hm.containsKey(aneighbor)){
18                 UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
19                 hm.put(aneighbor, newneighbor);
20                 DFS(hm, aneighbor);//DFS
21             }
22             hm.get(node).neighbors.add(hm.get(aneighbor));
23         }
24     }
复制代码


下面一种方法是DFS的非递归方法,中点是把BFS中的queue换成stack,因为出列方法不一样了,所以遍历的线路就不一样了。代码如下:
复制代码
1     public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         if(node == null)
 3             return null;
 4             
 5         HashMap<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
 6         LinkedList<UndirectedGraphNode> stack = new LinkedList<UndirectedGraphNode>();
 7         UndirectedGraphNode head = new UndirectedGraphNode(node.label);
 8         hm.put(node, head);
 9         stack.push(node);
10         
11         while(!stack.isEmpty()){
12             UndirectedGraphNode curnode = stack.pop();
13             for(UndirectedGraphNode aneighbor: curnode.neighbors){//check each neighbor
14                 if(!hm.containsKey(aneighbor)){//if not visited,then push to stack
15                     stack.push(aneighbor);
16                     UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
17                     hm.put(aneighbor, newneighbor);
18                 }
19                 
20                 hm.get(curnode).neighbors.add(hm.get(aneighbor));
21             }
22         }
23         
24         return head;
25     }
复制代码

 

转载于:https://www.cnblogs.com/fengmangZoo/p/4192777.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【iOS7一些总结】9、与列表显示(在):列表显示UITableView

列表显示&#xff0c;顾名思义它是在一个列表视图的形式显示在屏幕上的数据的内容。于ios在列表视图UITableView达到。这个类在实际应用中频繁&#xff0c;是很easy理解。这里将UITableView的主要使用方法总结一下以备查。UITableView定义在头文件UITableView.h中&#xff0c;详…

java聊天软件课程设计_[计算机课程设计] JAVA课程设计-聊天室

本系统基于C/S模式。新的时代,新的世纪,在当今这个发达的信息时代,网上办公,极为普遍,生活变的简单化,人们在家就可以办公,是信息化时代的标志.我经过多方的调查和研究,并灵活运用了自己所学的知识,编写了这个非常适用的一个小软件.它是通过RMI通信协议,利用JAVA的多线程技术,将…

iOS 获取手机信息

待续&#xff1b;转载于:https://www.cnblogs.com/xieyier/p/4194271.html

show status和show variables区别解析

1.show status 查看系统运行的实时状态&#xff0c;便于dba查看mysql当前运行的状态&#xff0c;做出相应优化&#xff0c;动态的&#xff0c;不可认为修改&#xff0c;只能系统自动update。MariaDB [(none)]> show status like %conn%;--------------------------------…

【Javascript 拾遗之三】Closure 闭包

说起闭包这个概念&#xff0c;其实是离散数学中的一种定义&#xff0c;而很程序员们耳熟能详但不一定能说清楚它的含义和用途。本文先简单地介绍下离散数学中的闭包&#xff0c;然后再探讨一下Javascript语言中的闭包是如何创建和应用的。 Closure 闭包 1、闭包的定义 -离散数学…

java递归空瓶换饮料_问题描述:一次买n瓶可乐,k个空瓶可以换一瓶饮料,那么一共能喝多少瓶饮料? | 学步园...

/***问题描述&#xff1a;一次买n瓶可乐&#xff0c;k个空瓶可以换一瓶饮料&#xff0c;那么一共能喝多少瓶饮料&#xff1f;*下面用不同的方法实现了这个问题(Java实现)&#xff1a;*1.递归方法*2.非递归方法*3.公式法*/public class CocaCola{public int Count(int n, int k)…

SpringMVC(一):环境搭建

2019独角兽企业重金招聘Python工程师标准>>> //TODO 转载于:https://my.oschina.net/u/1020238/blog/505272

DockPanel 类

DockPanel 类 .NET Framework 4.5其他版本此主题尚未评级 - 评价此主题定义您可水平或垂直排列子元素的区域&#xff0c;互相。 继承层次结构 System.Object System.Windows.Threading.DispatcherObjectSystem.Windows.DependencyObjectSystem.Windows.Media.VisualSystem.Wind…

java动态json入库_从JSon File动态生成模式

一些兴趣点&#xff1a;1)您不需要数据帧来加载您的json架构 . 模式在驱动程序上加载和执行&#xff0c;因为不需要分发那些不必要的开销2)我构造了一个JColumn对象的List&#xff0c;并将它传递给StructType以动态构造模式3)inferSchema应该是false&#xff0c;因为我们明确定…

【分布式计算】MapReduce的替代者-Parameter Server

原文&#xff1a;http://blog.csdn.net/buptgshengod/article/details/46819051 首先还是要声明一下&#xff0c;这个文章是我在入职阿里云1个月以来&#xff0c;对于分布式计算的一点肤浅的认识&#xff0c;可能有些地方不够妥善&#xff0c;还请看官可以指出不足的地方&#…

java迭代器逆序_迭代器

提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而又不需要暴露该对象的内部表示。迭代器模式(Iterator)实际上在Java的集合类中已经广泛使用了。我们以List为例&#xff0c;要遍历ArrayList&#xff0c;即使我们知道它的内部存储了一个Object[]数组&#xff0c;也不…

iOS开发多线程篇—线程安全

iOS开发多线程篇—线程安全 一、多线程的安全隐患 资源共享 1块资源可能会被多个线程共享&#xff0c;也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象、同一个变量、同一个文件 当多个线程访问同一块资源时&#xff0c;很容易引发数据错乱和数据安全问题 示例…

java程序可分为两个基本文件_1 Java语言概述答案

第1章 Java语言概述一、判断题1&#xff0e;Java语言是一种解释执行的语言&#xff0c;这个特点是Java语言的一个缺点。(F)2&#xff0e;Java源程序的文件名一定要与文件中某个类的名称一致。(T)3&#xff0e;Java语言采用面向对象的思想编程&#xff0c;具有跨平台、分布式、多…

JQuery中的siblings()是什么意思

siblings()函数用于选取每个匹配元素的所有同辈元素(不包括自己)&#xff0c;并以jQuery对象的形式返回。转载于:https://www.cnblogs.com/DTWolf/p/4807277.html

sql server 日期类型

下面是结果集&#xff1a; 数据类型 输出 time 12:35:29. 1234567 date 2007-05-08 smalldatetime 2007-05-08 12:35:00 datetime 2007-05-08 12:35:29.123 datetime2 2007-05-08 12:35:29. 1234567 datetimeoffset 2007-05-08 12:35:29.1234567 12:15 转载于:htt…

以太坊java接口_java以太坊库web3j文档

通过java打包以太坊智能合约Web3j可以自动打包智能合同代码&#xff0c;以便在不脱离JVM的情况下进行以太坊智能合同部署和交互。要打包代码&#xff0c;需要先编译智能合同&#xff1a;$ solc .sol --bin --abi --optimize -o /web3j solidity generate /path/to/.bin /path/t…

【Android车载系统 News | Tech 1】News 谷歌开发车载Android系统 2014-12-19

据外国媒体报道&#xff0c;Android和iOS两大操作系统在垄断手机和平板之后&#xff0c;开始向智能家居、智能汽车、客厅娱乐、物联网等领域扩张。谷歌和苹果此 前均推出了连接智能手机和车载信息系统的平台产品。2014年12月18日&#xff0c;谷歌正计划开发一种汽车信息系统使用…

Android Ion 框架 文件下载

为什么80%的码农都做不了架构师&#xff1f;>>> ion是的一个安卓异步网络和图片加载库。 特性 异步下载&#xff1a;下载图片 (用ImageViews 或者 Bitmaps显示)&#xff1b;下载JSON文件 (通过Gson解析)&#xff1b;下载字符串&#xff1b;下载文件&#xff1b;Flu…

php 加密保存mysql_PHP及MYSQL中字符串加密函数

【IT168 服务器学院】我们在写PHP程序时经常要对用户的口令加密以确保安全&#xff0c;这时就要用到一些加密的函数。我总结了以下几种方法写出来供大家参考。1、用MYSQL中的加密函数来加密&#xff1a;PASSWORD()我想&#xff0c;这是一种很常用的方法了&#xff0c;具体的实现…

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree;import java.util.Stack;public class BiTree {public static void main(String[] args) {// 首先构造叶子节点BiTree leafA1 new BiTree(4);BiTree leafA2 new BiTree(5);BiTree leafB1 new BiTree(6);BiTree leafB2 new BiTree(7);// 构建二…