[LeetCode]Clone Graph 克隆图

leetcode原题链接

这个题其实和Copy List with Random Pointer是一个思路

首先一点是,clone就是要把这个图完整的复制出来,也就是,每个node,和对应的neighbor关系都要复制出来。

其次, 题中说了没有重复的label,那么就说,每个点都是不一样的。然后,每个node都有邻居,所以那么我们在遍历的时候,不能把相同的点复制多个(比如1的邻居是【2,3】, 2的邻居是【1,3】,如果出现了2个【3】,就不对了)

思路是:

对于图的遍历,我们应该想到BFS,那么需要一个栈Queue, 用来一层一层的遍历图。那么如果能把原图和克隆图对应起来,那么就可一边遍历原图,一边创建克隆图。

我们可以看出这是个映射关系,用HashMap肯定是一个不错的选择。所以我们建了一个map,<key-当前图节点,value-克隆图节点>

然后我们做好准备工作:把原图node放入栈中,建一个新的复制节点newNode(作为复制图的初始节点,方便我们操作),把这个关系放在map中。

然后再理下思路:

现在我们有一个栈,栈里存放了最原始的node。那么我们开始循环,每次把栈里的点拿出来,访问它的邻居,把每个相邻节点都加到栈中,依次循环,直到栈不为空。这是BFS的思想。

那么对于这个题来说,既然我们已经有了当前复制节点newNode,那么它和相邻节点的关系就是原图里的关系。 但是我们要克隆,不能拿原图里的点来用。所以每次要新建一个克隆节点。注意:新建克隆节点,我们不需要管它的相邻节点neighbors,因为只是在内存中建立一个对象放入map中,后面当遍历到这个节点的时候,再去管他的neighbors,所以这是BFS,而不是DFS, 当时我就是这一点迷糊了,没理清思路。

当map中没有这样的关系(也就是说之前遍历其他点的相邻节点neighbors的时候没有访问过它)我们要新建一个节点,放在map中,value就是现在原图的节点的邻居的label。这样就是把newNode和它的neighbors连起来(newNode.list.add(..))同时和原图node的neighbors的关系建立起来,放到map中方便以后使用。

还有,如何能保证克隆的图里,没有重复元素呢 ?那就是只有在map中不存在这个点的时候,才把他们压入栈中,不然的话就会造成死循环。

   public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if(node==null) return null;
        UndirectedGraphNode newNode= new UndirectedGraphNode(node.label);
        HashMap<UndirectedGraphNode, UndirectedGraphNode> map= new HashMap<UndirectedGraphNode,UndirectedGraphNode>();
        Queue<UndirectedGraphNode> queue= new LinkedList<UndirectedGraphNode>();
        queue.offer(node);
        map.put(node, newNode);
        while(!queue.isEmpty()){
            UndirectedGraphNode temp= queue.poll(); 
            newNode=map.get(temp); //map中肯定有这个temp,第一个点我们在循环前就加入了,后面的点当第一次访问的时候都会加入,第二次访问直接拿出来.
            for(UndirectedGraphNode neighbor: temp.neighbors){
                
                if(!map.containsKey(neighbor)){
                    map.put(neighbor, new UndirectedGraphNode(neighbor.label));
                    queue.offer(neighbor);
                } 
                newNode.neighbors.add(map.get(neighbor));
            }
            }
        return map.get(node);
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值