第 2 日:复杂链表的复制
题目链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
题目
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
解题
-
使用Map集合
大致思路:
注意我们是要在内存中再复制一份相同的链表,其中结点中random对随机指向自己链表中的某一节点,所以我们只能先把链表复制好一部分(value和next),再去对每个结点random赋值。
那么random指向自己链表的结点又如何保持一致呢?
我们可以借用
map的key-value
映射,在刚开始第一次复制部分链表时,就将关系一一对应进去。然后在第二次同时遍历新旧链表中的结点,根据旧链表结点中random属性查找map中对应的新链表结点,然后将新链表中的当前结点random属性指向此节点就好了详细代码如下:
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null) return null;
Node h=head.next;//
Node newHead=new Node(head.val);//新链表的头部
Node pro=newHead;
//存储两条链表相同结点的对应关系
HashMap<Node, Node> map = new HashMap<>();
map.put(head,newHead);
//复制链表的value和next内容,并保存两条链表相同结点对应关系
while (h!=null){
Node node = new Node(h.val);
pro.next=node;
map.put(h,node);
pro=pro.next;
h=h.next;
}
//重新指向头部
h=head;
pro=newHead;
//修改复制链表中random指针的指向
while (h!=null){
Node node = map.get(h.random);
pro.random=node;
pro=pro.next;
h=h.next;
}
return newHead;
}
}