力扣https://leetcode-cn.com/problems/copy-list-with-random-pointer/给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝,复制这个链表,复制链表中的指针都不应指向原链表中的节点 。返回复制链表的头节点。也就是说,原链表和新链表除了存储的地址不同,其他的对应关系完全一致。
示例:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
本题我们借助Map集合来存储原链表节点和新链表节点
代码实现:
public class LeetCode138_CopyList {
private class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
public Node copyRandomList(Node head) {
if(head == null){
return null;
}
//遍历原链表,构造新节点,存在Map中
//Map<原链表节点,新链表节点>
Map<Node,Node> nodeMap = new HashMap<>();
for(Node i = head; i != null ; i = i.next){
//创建新链表的节点
Node node = new Node(i.val);
nodeMap.put(i,node);
}
//对新链表进行连接操作,新链表的next和原链表的一一对应,random也是一样
for (Node x = head; x != null;x = x.next){
nodeMap.get(x).next = nodeMap.get(x.next);
nodeMap.get(x).random = nodeMap.get(x.random);
}
//返回新链表的头节点,就是原链表头节点的映射
return nodeMap.get(head);
}
}
下图是对连接链表操作的图解:
可以看到,利用Map集合非常方便的解决了问题。另外,也许你会有这样的疑问:Map集合的value的值只能唯一呀,若链表中有值相等的节点还能有Map吗?其实,我们的Map存的的Node类型的值,也就是存放的地址,而不是整型数。