zoukankan      html  css  js  c++  java
  • 133克隆图 · Clone Graph

    [抄题]:

    克隆一张无向图,图中的每个节点包含一个 label 和一个列表 neighbors

    [思维问题]:

    [一句话思路]:

    先BFS克隆点(一个点+扩展所有邻居),再克隆邻居(一个点+扩展所有邻居)。

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1.  bfs的结果应该存在一个节点构成的数组中ArrayList<UndirectedGraphNode>,作为for(UndirectedGraphNode n: nodes)循环的已有上限,表示对点的统计
    2. 最后返回的是mapping.get(headnode);表示新克隆出来的图,不用新定义一个result,因为返回的不是数组

    [二刷]:

    1. 先取node, 再取出每个node的多个neighbor
    2. copy都只是循环,不是函数,不是没调用呢嘛
    3. node第一次既要进入queue,也要进入检查的set 
    4. bfs中返回一个新new出来的ArrayList<UndirectedGraphNode>
    5. corner case返回的是null,想想就知道

    [三刷]:

    1. bfs中,对每一个节点的每一个neighbor都要操作。因此必须循环套循环
    2. 二级循环中是对临时变量进行操作的,即 for (UndirectedGraphNode neighbor : head.neighbors)中的neighbor

    [四刷]:

    [五刷]:

    [总结]:

    1. DFS要有栈,可能会stackoverflow,所以尽量用BFS
    2. 为保证代码风格良好,特殊情况缩进放短的内容,一般情况不缩进放长的内容。 eg 特殊情况+{continue;} 而一般情况+{长语句;}

    [复杂度]:Time complexity: O(边数+点数) Space complexity: O(n)

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    1. 图和树的区别:从A到B有多条路径
    2. Queue的实现(右边)有:linkedlist arraylist pq, 实现之后才有offer等方法
    3. for (UndirectedGraphNode n : manynodes) ,前者是临时变量,后者是数组名,表示遍历。右边是范围上限

    [其他解法]:

    [Follow Up]:

    1. 无权图的最短路:哈希表distance(起点,到起点的距离)
    2. 克隆linkedlist, tree

    [LC给出的题目变变变]:

    138. Copy List with Random Pointer:也是先复制节点,再复制指针

    public class Solution {
        /*
         * @param node: A undirected graph node
         * @return: A undirected graph node
         */
        public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
            //HashMap
            HashMap<UndirectedGraphNode,UndirectedGraphNode> mapping = new HashMap<>();
            //corner case
            if (node == null) {
                return null;
            }
            //bfs
            ArrayList<UndirectedGraphNode> manynodes = bfs(node);
            //copy node
            for (UndirectedGraphNode n : manynodes) {
                mapping.put(n,new UndirectedGraphNode(n.label));
            }
            //copy neighbor
            for (UndirectedGraphNode n : manynodes) {
                UndirectedGraphNode newNode = mapping.get(n);
                for (UndirectedGraphNode neighbor : n.neighbors) {
                    UndirectedGraphNode newNeighbor = mapping.get(neighbor);
                    newNode.neighbors.add(newNeighbor);
                }
            }
            //return
            return mapping.get(node);
        }
        //bfs
        private ArrayList<UndirectedGraphNode> bfs(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)) {
                    queue.offer(neighbor);
                    set.add(neighbor);
                }
                }
            }
            return new ArrayList<UndirectedGraphNode>(set);
        }
    }
    View Code
  • 相关阅读:
    Java核心技术
    浏览器地址栏输入url回车之后发生了些什么
    Java相关面试题总结+答案(十)
    Java相关面试题总结+答案(九)
    Java相关面试题总结+答案(八)
    Java相关面试题总结+答案(七)
    input type=‘file’方法
    禁止用户复制网页内容
    js添加背景水印
    angular双向绑定
  • 原文地址:https://www.cnblogs.com/immiao0319/p/8392052.html
Copyright © 2011-2022 走看看