logo头像

不忘初心,奋力前行

copy list with random pointer

本文于397天之前发表,文中内容可能已经过时,如有问题,请联系我。

题目描述

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.Return a deep copy of the list.

题目解析

其实这个题目跟剑指offer里面题目35复制复杂链表是一样的。我们以下图为例

所以这个题也是分为三步:

  • 第一步:逐一复制A和B和C和D,复制后为A’、B’、C’和D’(加’是为了表示方便,实际上还是原来的值’),并把他们分别插入到原节点后面。
    代码如下:
    1
    2
    3
    4
    5
    for(p=head;p;p=p->next){
    copy = new RandomListNode(p->label);
    copy->next = p->next; // insert new at old next
    p = p->next = copy;
    }

for循环中的p=head就实现了这样的功能:

for循环里面第一个语句就是新建一个节点(例如A’),第二行就是把这个A’的next指针指向B(因为原本A的next就是B的地址),然后把A’的地址赋值给p->next,也就是说head->的next是A’(即第三行里面的p->next=copy)。

然后的把p->next的地址给p,也就是把copy的地址(A’)给p,这个时候p又指向了A’。
然后判断p是否是空呢?不是,那么就把p移动到下一个节点,也就是B了。然后再同理进行操作,直到最后一个节点复制完成,退出循环。这个时候结果如下:

  • 第二步:复制random结点。这一部分其实就是很简单,遍历A/B/C/D,然后判断这个节点(假设为X)的random指针有没有指向某个地方(也就是!nullptr),如果有的话就复制到相应的节点(A’)的random上。
    这部分也是很巧妙的利用了for循环的第三个参数和函数体里面的第一个语句实现了copy指向X’,p指向X(这里,假如此时p指向X,那么运行copy=p->next之后,copy指向了X,然后执行p=copy->next之后,p指向了(X+1),以此类推)。
1
2
3
4
for(p=head;p;p=copy->next){
copy = p->next; // copy random point
copy->random = (p->random?p->random->next:NULL);
}

此时的结果为

  • 第三步:断链。实现A->B->C->D,和A’->B’->C’->D’。先让p指向head,head是原本的ABCD那条链。因为我们要返回head,所以我们可以把head指向copy,然后操作copy即可。在for后面的第一个条件语句执行之后,p指向了A,copy和head指向了A’。然后下面自然就是进行断链操作了。断链结果如图所示。head指向的是copy,所以return head返回的就是图中下面的链。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
RandomListNode *copy,*p;
if (!head) return NULL;
for(p=head;p;p=p->next){
copy = new RandomListNode(p->label);
copy->next = p->next; // insert new at old next
p = p->next = copy;
}
for(p=head;p;p=copy->next){
copy = p->next; // copy random point
copy->random = (p->random?p->random->next:NULL);
}
for(p=head,head=copy=p->next;p;){
p = p->next = copy->next; // split list
copy = copy->next = (p?p->next:NULL);
}
return head;
}
};
支付宝打赏 微信打赏 QQ钱包打赏

感觉不错?欢迎给我 打个赏~我将不胜感激!