zoukankan      html  css  js  c++  java
  • 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的键值。

  • 相关阅读:
    Ubuntu vsftp复制文件到远端时错误,Permission denied
    linux 常用命令
    vbox安装ubuntu之后挂载共享文件夹无权限访问的问题以及改了主机名,导致命令行不能解析主机名的问题
    java 中的valueOf方法和强转
    读写文件,用代码在讲html文件转为jsp文件
    hibernate查询之后用el表达式取值时遇到的问题
    考研:操作系统:进程同步—信号量实现同步互斥(PV操作)
    考研:操作系统:处理机调度——几种经典的调度算法
    KMP算法
    mysql出现ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' 错误
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5596797.html
Copyright © 2011-2022 走看看