一.前言
嗨嗨嗨,大家好久不见。已经有好几天没更新了。今天我们就分享一道链表题吧——随即链表的复制https://leetcode.cn/problems/copy-list-with-random-pointer废话不多说,让我们直接开始今天的题目分享吧。
二.正文
1.1题目描述
他和单链表不同的是,结构体里还多一个random指针,指向随机节点。
这道题的意思就是想让我们将原链表完全复制下来,并且将复制好的链表返回到服务器上。
1.2题目分析
(i)创建节点,并尾插到原节点后
这道题我们可以通过遍历一个节点的同时,就穿插一个复制该节点数据的复制节点在该节点后面。
通过循环语句,我们最后会得到一个每一个原节点的后面尾插了一个新的复制节点。如图所示:
这里我们只是先处理了next指针,下面我们将处理random指针。让复制节点的random指针指向和原节点保持一致。
值得注意的是上面的这些节点是我们通过malloc函数自己手动创建的。红叉的地方意味着原来的next指向断掉了。
(ii)将复制节点的random指针指向正确位置
这里我们需要让复制节点的random指针和原节点指向一致,但不是指向原节点,而是指向复制节点。
如果原节点的random指针指向为NULL,那么与之对应的,该节点的复制节点也需要指向NULL。
如果该节点(假设l1)的random指针不指向NULL。而是指向另外一个节点(假设为l2)。那么与之对应的,l1的复制节点的random也应该指向l2的复制节点。那么这一步该如何实现呢?
我们假设一个指针pcur现在指向第三个节点13。pcur->next->random=pcur->random->next。
这样两个复制节点就可以通过pcur建立联系了。如图所示:
(iii)将复制链表从原链表上剥离下来
这里我们可以创建一个哨兵位,然后陆续从后面插入我们需要的复制节点即可。然后将哨兵位后面的有效节点存起来,在哨兵位free掉,归还给操作系统,将指向该哨兵位节点的指针置为NULL。最后返回之前存的有效节点即可
1.3代码实现
*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/
typedef struct Node ListNode;
struct Node* copyRandomList(struct Node* head)
{if(head==NULL)return head;ListNode* pcur = head;while (pcur){ListNode* copy = (ListNode*)malloc(sizeof(ListNode));copy->val = pcur->val;copy->next = pcur->next;pcur->next = copy;pcur = pcur->next->next;}pcur = head;while (pcur){ListNode* copy = pcur->next;if (pcur->random == NULL)copy->random= NULL;elsepcur->next->random = pcur->random->next;pcur = copy->next;}ListNode* newhead = (ListNode*)malloc(sizeof(ListNode));ListNode* ppcur;ppcur = newhead;pcur = head->next;int count = 0;while (pcur){if (count % 2 == 0){ppcur->next = pcur;ppcur = ppcur->next;}pcur = pcur->next;count++;}ListNode* ret = newhead->next;free(newhead);newhead = NULL;return ret;
}
值得注意的是上面的代码是在力扣环境上运行的。
三.前言
今天的分享就到此结束喽,咱们下次再见,拜拜。