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
         /          \_/

这题目的是clone 图,那么遍历原图建立新图的过程不可避免,用BFS或者DFS都可以。但是一点是如何建立将原图之间的结点链接映射到新图当中,old_node,new_node这样的键值对不可避免,需要用到一个hashmap,另外无论DFS还是BFS都需要判断当前的点有没有重复遍历,所以hashmap一箭双雕,

即一个查原图点有没有遍历过,另外对已经遍历的点,建立旧点和新点的映射。值得注意的是,这题给出的图的定义比较坑,即临接边只会出现在其中一个顶点的临接表中,另外一个不会出现。所以处理当前点的邻居时,不管该邻居之前有没有被遍历过,链接都需要建立。

BFS代码如下:

class Solution(object):
    def cloneGraph(self, node):
        """
        :type node: UndirectedGraphNode
        :rtype: UndirectedGraphNode
        """
        if not node:
            return None
        map = {}
        queue = collections.deque()
        queue.append(node)
        newNode = UndirectedGraphNode(node.label)
        map[node] = newNode
        while queue:
            oldNode = queue.popleft()
            for neighbor in oldNode.neighbors:
                if neighbor not in map:
                    newNode = UndirectedGraphNode(neighbor.label)
                    map[neighbor] = newNode
                    queue.append(neighbor)
                map[oldNode].neighbors.append(map[neighbor])

        return map[node]

DFS非递归遍历如下:

class Solution(object):
    def cloneGraph(self, node):
        """
        :type node: UndirectedGraphNode
        :rtype: UndirectedGraphNode
        """
        if not node:
            return None
        map = {}
        stack = [node]
        map[node.label] = UndirectedGraphNode(node.label)
        while stack:
            cur = stack.pop()
            for neighbor in cur.neighbors:
                if neighbor.label not in map:
                    map[neighbor.label] = UndirectedGraphNode(neighbor.label)
                    stack.append(neighbor)
                map[cur.label].neighbors.append(map[neighbor.label])
        return map[node.label]

DFS递归遍历:

class Solution(object):
    def cloneGraph(self, node):
        """
        :type node: UndirectedGraphNode
        :rtype: UndirectedGraphNode
        """
        if not node:
            return None
        map = {}
        map[node] = UndirectedGraphNode(node.label)
        self.dfs(node, map)
        return map[node]
    def dfs(self, node, map):
        for neighbor in node.neighbors:
            if neighbor not in map:
                map[neighbor] = UndirectedGraphNode(neighbor.label)
                self.dfs(neighbor, map)
            map[node].neighbors.append(map[neighbor])

这三种做法的时间复杂度都是O(V+E),结点入栈或者队列一次,出一次,边也要扫一次,判断。注意这题结点的值都不一样,为了节省空间,可以只使用原结点的值做hashmap的键值。

时间: 2024-10-05 22:32:33

Clone Graph的相关文章

21. Clone Graph

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 an

[leecode]Clone Graph

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 an

【leetcode】Clone Graph(python)

类似于二叉树的三种遍历,我们可以基于遍历的模板做很多额外的事情,图的两种遍历,深度和广度模板同样也可以做很多额外的事情,这里举例利用深度优先遍历的模板来进行复制,深度优先中,我们先访问第一个结点,接着访问第一个邻接点,再访问邻节点的邻节点.... class Solution: # @param node, a undirected graph node # @return a undirected graph node def cloneGraph(self, node): if None =

leetcode题目: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 n

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 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 lab

[Leetcode][JAVA] Clone Graph, Copy List with Random Pointer

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 a

[LintCode] Clone Graph

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 an

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 n

【leetcode】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 neigh

LeetCode: Clone Graph [133]

[题目] 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