题目解读
复制链表,这个链表带随机指针
https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/fu-zhi-dai-sui-ji-zhi-zhen-de-lian-biao-c2nvs/
思路
不是很会,找到一个很清晰的题解:
这里是引用(迭代) O(n)O(n)
题目要求我们复制一个长度为 n 的链表,该链表除了每个节点有一个指针指向下一个节点外,还有一个额外的指针指向链表中的任意节点或者null,如下图所示:
如何去复制一个带随机指针的链表?
首先我们可以忽略 random 指针,然后对原链表的每个节点进行复制,并追加到原节点的后面,而后复制 random
指针。最后我们把原链表和复制链表拆分出来,并将原链表复原。图示过程如下:
1、在每个节点的后面加上它的复制,并将原链表和复制链表连在一起。
2、 从前往后遍历每一个原链表节点,对于有 random 指针的节点 p,我们让它的 p->next->random = p->random->next,这样我们就完成了对原链表 random 指针的复刻。
3、最后我们把原链表和复制链表拆分出来,并将原链表复原。
具体过程如下:
1、定义一个 p 指针,遍历整个链表,复制每个节点,并将原链表和复制链表连在一起。
2、再次遍历整个链表,执行p->next->random = p->random->next,复制random 指针。
3、定义虚拟头节点 dummy,用来指向复制链表的头节点, 将两个链表拆分并复原原链表。
class Solution { public:
> Node* copyRandomList(Node* head) {
> for(auto p = head; p; p = p->next->next) //复制每个节点,并将原链表和复制链表连在一起。
> {
> auto q = new Node(p->val);
> q->next = p->next;
> p->next = q;
> }
>
> for(auto p = head; p; p = p->next->next) //复制random指针
> {
> if(p->random)
> p->next->random = p->random->next;
> }
>
> //拆分两个链表,并复原原链表
> auto dummy = new Node(-1), cur = dummy;
> for(auto p = head; p; p = p->next)
> {
> auto q = p->next;
> cur = cur->next = q;
> p->next = q->next;
> }
>
> return dummy->next;
> } };
作者:lin-shen-shi-jian-lu-k
链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/fu-zhi-dai-sui-ji-zhi-zhen-de-lian-biao-c2nvs/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
收获
1.https://www.cnblogs.com/KunLunSu/p/7861330.html讲auto的用法,就是替代数据类型。
2.` for(auto p = head; p; p = p->next->next) //复制每个节点,并将原链表和复制链表连在一起。
3.
for(auto p = head; p; p = p->next->next) //复制每个节点,并将原链表和复制链表连在一起。
> {
> auto q = new Node(p->val);
> q->next = p->next;
> p->next = q;
> }
- p = 1 2 3 4 5 auto p = head
- q = 1 auto q = new Node(p->val);
- q = 1 2 3 4 5 q->next = p->next;
- p = 1 1 2 3 4 5 p->next = q;
- p = 2 3 4 5 p = p->next->next
for(auto p = head; p; p = p->next->next) //复制random指针
> {
> if(p->random)
> p->next->random = p->random->next;
> }
- p = 1 1 2 2 3 3 4 4 5 5
- 如果当前节点存在random,
p->next->random = p->random->next;
把random指向的节点给复制的新节点
auto dummy = new Node(-1), cur = dummy;
> for(auto p = head; p; p = p->next)
> {
> auto q = p->next;
> cur = cur->next = q;
> p->next = q->next;
> }
>
> return dummy->next;
cur = cur->next = q;
cur->next = q;
cur = cur->next;
- p = 1 1 2 2 3 3 4 4 5 5
- q = 1 2 2 3 3 4 4 5 5 q = p->next;
- cur = 0 1 2 2 3 3 4 4 5 5 cur->next = q;
- cur = 1 2 2 3 3 4 4 5 5 cur= cur->next;
- p = 1 2 2 3 3 4 4 5 5 p ->next =q->next;
- p = 2 2 3 3 4 4 5 5 p = p->next
- q = 2 3 3 4 4 5 5
- cur = 1 2 3 3 4 4 5 5
- cur = 2 3 3 4 4 5 5
- p = 2 3 3 4 4 5 5
- p = 3 3 4 4 5 5
- …
- dummy = 0 1 2 3 4 5
- return dummy->next;