Leetcode | 133克隆图

给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。

图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。

class Node {
public int val;
public List neighbors;
}

测试用例格式:

简单起见,每个节点的值都和它的索引相同。例如,第一个节点值为 1(val = 1),第二个节点值为 2(val = 2),以此类推。该图在测试用例中使用邻接列表表示。

邻接列表 是用于表示有限图的无序列表的集合。每个列表都描述了图中节点的邻居集。

给定节点将始终是图中的第一个节点(值为 1)。你必须将 给定节点的拷贝 作为对克隆图的引用返回。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/clone-graph

代码思路:
这道题的主要目的是遍历一遍图,然后把图的每一个节点copy一份,主要的难点在于如何找到自己已经创建过得节点,如何管理题目给出的node节点,和自己的node节点的对应关系,保证对相对应的节点做相同的操作。最难的点在于debug,由于leetcode的返回并不会告诉你哪一个节点出现问题了,也没有个过程,同时调试的时候node节点是node的指针值,也难以辨认。
代码如下:

public Node cloneGraph(Node node) {
		Queue<Node> que=new LinkedList<Node>();
		Queue<Node> quecopy=new LinkedList<Node>();
		HashSet<Integer> set=new HashSet<Integer>();
		HashMap<Integer,Node> setcopy=new HashMap<Integer,Node>();
		que.add(node);
		Node result=new Node(1,new ArrayList());
		setcopy.put(1, result);
		Node resultcurr=result;
		Node temp;
		Node curr;
		quecopy.add(result);
		while(!que.isEmpty()) {
			curr=que.remove();
			resultcurr=quecopy.remove();
			if(!set.contains(curr.val)) {
				set.add(curr.val);
				resultcurr.val=curr.val;
				//System.out.println("copy第"+curr.val+"个节点");
				for(Node one :curr.neighbors) {
					if(!setcopy.containsKey(one.val)) {
						//System.out.println("邻居节点有:新建"+one.val+" ");
						que.add(one);
						temp=new Node(one.val,new ArrayList());
						setcopy.put(temp.val, temp);
						quecopy.add(temp);
						resultcurr.neighbors.add(temp);
					}else {
						//System.out.println("邻居节点有:"+one.val+" ");
						temp=setcopy.get(one.val);
						resultcurr.neighbors.add(temp);
					}
				}
				System.out.println();
			}
		}
		return result;
    }
	

代码分析:
时间复杂度和官方的解答是一致的,但是空间的复杂度,我这个方法会高出很多,因为,我不但多使用了一个quecopy去存储自己创建的节点队列,和que队列一同增减保证对相对应的节点做相同的操作。还多使用了一个setcopy用来找到自己创建的节点。
官方的代码总体思路是很简单的,但是官方代码将自己创建的节点放到了hashmap中,一方面可以方便的知道哪些节点是访问过得,也能找到创建过得节点,最后从hashmap中返回结果,也是非常巧妙了。

博主代码结果如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值