一.前言
嗨嗨嗨,大家好久不见。已经有好几天没更新了。今天我们就分享一道链表题吧——随即链表的复制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;
else
pcur->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;
}
值得注意的是上面的代码是在力扣环境上运行的。
三.前言
今天的分享就到此结束喽,咱们下次再见,拜拜。