题目描述:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
题解:
记原链表为p1
-
先拷贝一份只有val和next指向链表p2.
-
将俩个链表p1和p2糅合在一个链表中:在p1不为空的情况下p2.next = p1.next; 3. p1.next = p2;
即:
-
再将p1指向head
-
进行random指向的拷贝:在p1不为空的情况下,p2.random = p1.random.next; p1 = p2.next; p2 = p1.next;
-
再将p1指向head
便于分辨,我们将当前复制的链表结点都全上蓝色圆圈
- 拆表:p1.next = p2.next; 在p2.next不为空的情况下p2.next = p2.next.next;反之p1 = p1.next;
如上,橙色的为原链表,蓝色为拷贝链表。
代码实现:
public static Node complexCopy(Node head){
if(head == null){
return null;
}
//糅合俩个链表
Node p1 = head;
while(p1 != null){
Node p2 = new Node(p1.val);
p2.next = p1.next;
p1.next = p2;
p1 = p2.next;
}
//2.复制random指向
p1 = head;
while(p1 != null){
Node p2 = p1.next;
if(p1.random != null) {
p2.random = p1.random.next;
}
p1 = p2.next;
}
//3.拆表
p1 = head;
Node newHead = head.next;
while(p1 != null) {
Node p2 = p1.next;
p1.next = p2.next;
if (p2.next != null) {
p2.next = p2.next.next;
}
p1 = p1.next;
}
return newHead;
}