请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
链接:leetcode
解题思路:不同于简单列表的复制,这个多了一个随机指针。如果是简单列表,直接构造一个新的列表,将老链表遍历复制数据就好了。但是,随机指针就不能这么做了,因为随机指针指向的可能是还没有遍历的到节点,那就没法指了。
所以,一种思路是这样的。三次遍历,第一次遍历,复制一个新的节点到每两个旧节点中间。第二次遍历,将新节点的随机指针指向被复制的旧节点的随机指针的下一个节点(看代码就懂了)。第三次遍历,将新旧节点分开,得到两个新旧链表。
需要注意的问题,在第二次遍历的时候,复制随机节点可能是null的,如果是null,那就直接将随机指针置为null就好了。
在第三次遍历的时候,需要预判是不是到了尾节点,这样就能把新链表的尾节点的next指向null。
/*
// 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 head;
Node cur = head;
while(cur != null) {
Node temp = cur.next;
cur.next = new Node(cur.val);
cur.next.next = temp;
cur = temp;
}
cur = head;
while(cur != null) {
cur.next.random = cur.random == null ? null : cur.random.next;
cur = cur.next.next;
}
cur = head;
Node res = cur.next;
while(cur != null) {
Node temp = cur.next;
cur.next = temp.next;
temp.next = cur.next == null ? null : cur.next.next;
cur = cur.next;
}
return res;
}
}