1 题目链接
2 题目描述
描述
现在有一个这样的链表:链表的每一个节点都附加了一个随机指针,随机指针可能指向链表中的任意一个节点或者指向空。
请对这个链表进行深拷贝。
涉及到的链表结构
// 普通链表
class RandomListNode{
int val;
ListNode next;
ListNode random;
public RandomListNode(x){
this.val = x;
}
}
3 代码思路
如果是普通链表,遍历一遍即可实现深度拷贝,这道题目的难点在于怎么样拷贝链表的随机指针。试想如果我们使用普通链表的拷贝方法,拷贝过来的新链表将无法得知随机指针指向的结点是哪一个。
换个思路,为了保证我们能够准确得找到新链表结点随机指针指向的位置,我们可以借助原链表知道自己随机指针指向的结点这一特点。
分为三个步骤,首先复制原来链表的结点,并插入到复制结点的后边,即复制结点。接着,通过原来链表随机指针指向结点,找到新链表结点随机指针指向的结点,即复制随机指针。最后,将原链表和新链表分离开来。实现深度拷贝。
4 代码实现
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return null;
// 创建新结点插入到原结点后边
RandomListNode cur = head;
while(cur != null){
RandomListNode temp = new RandomListNode(cur.label);
temp.next = cur.next;
cur.next = temp;
cur = cur.next.next;
}
// 复制随机指针
cur = head;
while(cur != null){
if(cur.random != null){
cur.next.random = cur.random.next;
}
cur = cur.next.next;
}
// 把拷贝链表和原链表分离
cur = head;
RandomListNode newHead = cur.next;
RandomListNode rp = newHead;
while(cur != null){
cur.next = rp.next;
if(cur.next != null){
rp.next = cur.next.next;
}
cur = cur.next;
rp = rp.next;
}
return newHead;
}
}