Clone Graph leetcode java(DFS and BFS 基础)
题目:
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 #.
- First node is labeled as
0. Connect node0to both nodes1and2. - Second node is labeled as
1. Connect node1to node2. - Third node is labeled as
2. Connect node2to node2(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/ 题解:
这道题考察对图的遍历和利用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
procedure DFS(G,v):
label v as discovered
for all edges from v to w in G.adjacentEdges(v) do
if vertex w is not labeled as discovered then
recursively call DFS(G,w)
非递归写法的DFS伪代码如下:
Input: A graph G and a root v of G
procedure DFS-iterative(G,v):
let S be a stack
S.push(v)
while S is not empty
v ← S.pop()
if v is not labeled as discovered:
label v as discovered
for all edges from v to w in G.adjacentEdges(v) do
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 graph
when 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
end if
for all edges e in G.adjacentEdges(t) loop
u ← G.adjacentVertex(t,e)
if u is not in V then
add u to V
enqueue u onto Q
end if
end loop
end loop
return none
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);
while(!queue.isEmpty()){
UndirectedGraphNode curnode = queue.poll();
for(UndirectedGraphNode aneighbor: curnode.neighbors){//check each neighbor
if(!hm.containsKey(aneighbor)){//if not visited,then add to queue
queue.add(aneighbor);
UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
hm.put(aneighbor, newneighbor);
}
hm.get(curnode).neighbors.add(hm.get(aneighbor));
}
}
return head;
}
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
return head;
}
public void DFS(HashMap<UndirectedGraphNode, UndirectedGraphNode> hm, UndirectedGraphNode node){
if(node == null)
return;
for(UndirectedGraphNode aneighbor: node.neighbors){
if(!hm.containsKey(aneighbor)){
UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
hm.put(aneighbor, newneighbor);
DFS(hm, aneighbor);//DFS
}
hm.get(node).neighbors.add(hm.get(aneighbor));
}
}
下面一种方法是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);
while(!stack.isEmpty()){
UndirectedGraphNode curnode = stack.pop();
for(UndirectedGraphNode aneighbor: curnode.neighbors){//check each neighbor
if(!hm.containsKey(aneighbor)){//if not visited,then push to stack
stack.push(aneighbor);
UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
hm.put(aneighbor, newneighbor);
}
hm.get(curnode).neighbors.add(hm.get(aneighbor));
}
}
return head;
}
Clone Graph leetcode java(DFS and BFS 基础)的更多相关文章
- Clone Graph [LeetCode]
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- Clone Graph——LeetCode
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- 【万能的DFS和BFS基础框架】-多刷题才是硬道理!
- 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 ...
- Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph)
Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree ...
- [LeetCode] 133. Clone Graph 克隆无向图
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- LeetCode: Clone Graph 解题报告
Clone GraphClone an undirected graph. Each node in the graph contains a label and a list of its neig ...
- [Leetcode Week3]Clone Graph
Clone Graph题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/clone-graph/description/ Description Clon ...
- 【LeetCode】133. Clone Graph 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...
随机推荐
- [转载]C#使用Interlocked进行原子操作
原文链接:王旭博客 » C# 使用Interlocked进行原子操作 什么是原子操作? 原子(atom)本意是"不能被进一步分割的最小粒子",而原子操作(atomic operat ...
- CSS3与页面布局学习笔记(七)——前端预处理技术(Less、Sass、CoffeeScript、TypeScript)
CSS不像其它高级语言一样支持算术运算.变量.流程控制与面向对象特性,所以CSS样式较多时会引起一些问题,如修改复杂,冗余,某些别的语言很简单的功能实现不了等.而javascript则是一种半面向对象 ...
- jquery模拟LCD 时钟
查看效果网址:http://keleyi.com/keleyi/phtml/jqtexiao/24.htm 以下是HTML文件源代码: <!DOCTYPE html PUBLIC "- ...
- 钉钉js依赖库学习
看别人用的依赖库的好处在于,你知道有什么可以用,什么可以借鉴.(钉钉——协作桌面应用) PS:人最怕是不知道,而不是你不会. 1. jQuery 钉钉使用了1.9.1版本的jQuery,jQuery作 ...
- 在 ASP.NET MVC 中充分利用 WebGrid (microsoft 官方示例)
在 ASP.NET MVC 中充分利用 WebGrid https://msdn.microsoft.com/zh-cn/magazine/hh288075.aspx Stuart Leeks 下载代 ...
- SQL Server Integration Services(SSIS) 包配置与部署
SSIS配置此处的配置方式,主要针对到正式服务器上要修改服务器名,和连接服务器等配置注意:1. 包配置在windows2008上生成后,在windows2003上mysql的配置无法使用,总是报错连接 ...
- 运行时报错:java.net.BindException: Address already in use: JVM_Bind <null>:8080 (或8009或8005)
修改Tomcat端口号步骤:1.找到Tomcat目录下的conf文件夹2.进入conf文件夹里面找到server.xml文件3.打开server.xml文件(打开方式选择记事本)4.在server.x ...
- 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接(转)
1.内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符).包括相等联接和自然联接. 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...
- HTML5 兼容IE浏览器
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- MySQL InnoDB表--BTree基本数据结构
MySQL InnoDB表是索引组织表这一点应该是每一个学习MySQL的人都会首先学到的知识,这代表这表中的数据是按照主键顺序存储,也就是说BTree的叶子节点存储了所有该行的数据. 我最开始是搞Or ...