• lintcode137- Clone Graph- medium


    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

    How we serialize an undirected graph:

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

    Example

    return a deep copied graph.

    三步走。1. BFS 得到nodes Arraylist  2. copy nodes  3. copy edges

    数据结构:map(节点映射), queue(BFS)+set(BFS时避免加重复)

    反正一定得要先2再3,没办法同时做,但你没必要23都各自做一次BFS,可以先1BFS把节点有多少个的信息提取出来,给后面直接用。

    另外切记queue.offer()和set.add()一定要同时进行!分开后在重复加某条边的操作下会出错。

    1. 自己实现(两次BFS有点冗余了,学习下)

    /**
     * Definition for undirected graph.
     * class UndirectedGraphNode {
     *     int label;
     *     ArrayList<UndirectedGraphNode> neighbors;
     *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
     * };
     */
    
    
    public class Solution {
        /*
         * @param node: A undirected graph node
         * @return: A undirected graph node
         */
        public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
            // write your code here
            if (node == null) {
                return null;
            }
            
            Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
            Queue<UndirectedGraphNode> queue = new LinkedList<>();
            queue.offer(node);
            
            while (!queue.isEmpty()) {
                UndirectedGraphNode crt = queue.poll();
                UndirectedGraphNode crtCopy = new UndirectedGraphNode(crt.label);
                map.put(crt, crtCopy);
                for (UndirectedGraphNode neighbor: crt.neighbors) {
                    if (!map.containsKey(neighbor)) {
                        queue.offer(neighbor);
                    }
                }
            }
            
            Set<UndirectedGraphNode> nodeProcessed = new HashSet<>();
            // queue的offer和set的add一定要同步进行!!!在别的地方add可能会出错处理重复情况
            queue.offer(node);
            nodeProcessed.add(node);
            while (!queue.isEmpty()) {
                UndirectedGraphNode crt = queue.poll();
                UndirectedGraphNode crtCopy = map.get(crt);
                for (UndirectedGraphNode neighbor: crt.neighbors) {
                    UndirectedGraphNode neighborCopy = map.get(neighbor);
                    crtCopy.neighbors.add(neighborCopy);
                    if (!nodeProcessed.contains(neighbor)) {
                        queue.offer(neighbor);
                        nodeProcessed.add(neighbor);
                    }
                }
            }
            
            return map.get(node);
        }
    }

    2.九章实现(额外函数以模块化也值得学习)

    public class Solution {
        /**
         * @param node: A undirected graph node
         * @return: A undirected graph node
         */
        public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
            if (node == null) {
                return node;
            }
    
            // use bfs algorithm to traverse the graph and get all nodes.
            ArrayList<UndirectedGraphNode> nodes = getNodes(node);
            
            // copy nodes, store the old->new mapping information in a hash map
            HashMap<UndirectedGraphNode, UndirectedGraphNode> mapping = new HashMap<>();
            for (UndirectedGraphNode n : nodes) {
                mapping.put(n, new UndirectedGraphNode(n.label));
            }
            
            // copy neighbors(edges)
            for (UndirectedGraphNode n : nodes) {
                UndirectedGraphNode newNode = mapping.get(n);
                for (UndirectedGraphNode neighbor : n.neighbors) {
                    UndirectedGraphNode newNeighbor = mapping.get(neighbor);
                    newNode.neighbors.add(newNeighbor);
                }
            }
            
            return mapping.get(node);
        }
        
        private ArrayList<UndirectedGraphNode> getNodes(UndirectedGraphNode node) {
            Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
            HashSet<UndirectedGraphNode> set = new HashSet<>();
            
            queue.offer(node);
            set.add(node);
            while (!queue.isEmpty()) {
                UndirectedGraphNode head = queue.poll();
                for (UndirectedGraphNode neighbor : head.neighbors) {
                    if(!set.contains(neighbor)){
                        set.add(neighbor);
                        queue.offer(neighbor);
                    }
                }
            }
            
            return new ArrayList<UndirectedGraphNode>(set);
        }
    }
  • 相关阅读:
    spring事件广播
    浏览器中文乱码,组合项目中部分模块乱码
    SpringSecurity加密Salt
    Linux服务器Java输出文件中文乱码
    重定向监听端口并持久化路由配置
    Mac下文件编码转换
    Shell之内容匹配与格式输出
    [leetcode]Scramble String
    [leetcode]Decode Ways
    [leetcode]Valid Palindrome
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7726819.html
Copyright © 2020-2023  润新知