题目
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深度拷贝。
考点
1.hash 空间换时间 On^2->On
2.双指针,野指针的鲁棒判断
思路
1.复制节点到原链表后面。
copy->link->next 。只复制节点的值和next,不复制随机指针。cloneNode->random=nullptr;
2.复制对应的随机指针。
重置双指针->如果原节点有随机指针就copy->next
3.分解两个链表。
重新赋值两个指针->ori先走->clone后走->next
代码
/*
* @lc app=leetcode.cn id=138 lang=cpp
*
* [138] 复制带随机指针的链表
*
* https://leetcode-cn.com/problems/copy-list-with-random-pointer/description/
*
* algorithms
* Medium (23.92%)
* Total Accepted: 3.6K
* Total Submissions: 15.1K
* Testcase Example: '{}'
*
* 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
*
* 要求返回这个链表的深度拷贝。
*
*/
/**
* 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) {
if(!head )
return head;
//1.clone linked list
RandomListNode *oriNode = head;
while(oriNode)
{
RandomListNode *cloneNode = new RandomListNode(0);
//copy
cloneNode->label = oriNode->label;
cloneNode->next = oriNode->next;
cloneNode->random = nullptr;
//link
oriNode->next = cloneNode;
//next
oriNode = cloneNode->next;
}
//2.clone random pointer
oriNode = head;
while(oriNode)
{
//cloneNode
RandomListNode *cloneNode = oriNode->next;
//copy randomNode
if(oriNode->random)
{
RandomListNode *oriRandom = oriNode->random;
cloneNode->random = oriRandom->next;//是原随机指针的next,不是原随机指针!
}
//next oriNode
oriNode = cloneNode->next;
}
//3.depart
//return:cloneHead
RandomListNode *cloneHead = head->next;
RandomListNode *cloneNode = cloneHead;
//oriNode Traversing from head
oriNode = head;
while(oriNode)
{
//oriNode first
oriNode->next = cloneNode->next;
oriNode = oriNode->next;
//cloneNode second
if(!oriNode)
break;
cloneNode->next = oriNode->next;
cloneNode = cloneNode->next;
}
return cloneHead;
}
};
二刷
* 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
*
* 要求返回这个链表的深度拷贝。
*
*/
/**
* 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)
{
if(!head)
return head;
//clone
RandomListNode* oriNode=head;
while(oriNode)
{
//copy
RandomListNode* cloneNode=new RandomListNode(0);
cloneNode->label=oriNode->label;
cloneNode->next=oriNode->next;
cloneNode->random=nullptr;
//link
oriNode->next=cloneNode;
//next
oriNode=cloneNode->next;
}
//copy random
oriNode=head;
while(oriNode)
{
RandomListNode* cloneNode=oriNode->next;
//copy
if(oriNode->random)
{
cloneNode->random=oriNode->random->next;
}
//next
oriNode=cloneNode->next;
}
//depart
oriNode=head;
RandomListNode* cloneNode=head->next;
RandomListNode* cloneHead=cloneNode;//return
while(oriNode)
{
oriNode->next=cloneNode->next;
oriNode=oriNode->next;
if(!oriNode)
break;
cloneNode->next=oriNode->next;
cloneNode=cloneNode->next;
}
return cloneHead;
}
};