克隆图的思路探讨与源码
克隆图的题目如下图,该题属于图和搜索类型的题目,主要考察对于搜索方法的使用和图结构遍历的理解。本文的题目作者想到2种方法,分别是DFS深度优先搜索和BFS广度优先搜索方法,其中BFS广度优先搜索方法使用Java进行编写,而DFS深度优先搜索方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用BFS广度优先搜索方法进行解决,首先判断传入的图是否为空,如果是就直接返回空的结果。然后初始化一个哈希map、再将第一个节点进行初始化并放进一个队列里面,将第一个节点和它的克隆体放在map里面。然后开始遍历队列的列表,只要它不为空就循环遍历,在遍历内部是将队列的头部弹出一个元素,再用for循环去遍历搜索该元素的邻居列表里面的元素是否被map所包含(是否被访问过),如果没有被访问过就进行克隆,然后放入元素到队列的列表里面,并且更新当前元素的邻居列表。按照这个思路最终返回克隆后的结果。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public Node cloneGraph(Node node) {
if(node == null){
return null;
}
Map<Node,Node> mapSearch = new HashMap<>();
Node vertex = new Node(node.val,new ArrayList<>());
Deque<Node> queueList = new LinkedList<>();
mapSearch.put(node,vertex);
queueList.offer(node);
while (!queueList.isEmpty()) {
Node ndx = queueList.poll();
for (Node v:ndx.neighbors) {
if (!mapSearch.containsKey(v)) {
mapSearch.put(v,new Node(v.val,new ArrayList<>()));
queueList.offer(v);
}
mapSearch.get(ndx).neighbors.add(mapSearch.get(v));
}
}
return vertex;
}
}
显然,我们看到BFS广度优先搜索的方法的效果还行,同时还可以使用DFS深度优先搜索的方法。首先是初始化一个字典,然后设计一个深度优先搜索遍历函数,首先判断图是否为空,如果是则直接返回空,然后判断这个图是否已经在字典里面,如果是就直接返回字典的这个元素的映射值。然后对当前节点的元素进行克隆,并将这个克隆信息保存在字典里面,循环遍历当前元素的邻居列表,获取内部的元素再次进行深度遍历搜索并更新邻居列表的信息,最终返回克隆结果。然后用传入的图调用这个DFS深度优先搜索函数即可,返回的深度优先搜索结果直接返回就是最终的克隆结果。所以按照这个思路就可以解决,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def cloneGraph(self, node: 'Node') -> 'Node':
mapSearch = {}
def dfsSearch(node):
if(not node):
return
if(node in mapSearch):
return mapSearch[node]
vertex = Node(node.val,[])
mapSearch[node] = vertex
for v in node.neighbors:
vertex.neighbors.append(dfsSearch(v))
return vertex
return dfsSearch(node)
从结果来说Java版本的BFS广度优先搜索方法的效率还可以,而Python版本的DFS深度优先搜索方法的速度一般,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。