文章目录
138. 随机链表的复制
思路:
- 完成节点数据拷贝——在原链表的每个节点后面增加一个拷贝节点,拷贝节点的值等于原节点的值
- 完成节点的随机指针拷贝——原节点的随机指针指向哪里,拷贝节点就指向对应节点的下一个节点(这一部分是这条思路能实现的关键)
- 完成节点的next指针拷贝——将拷贝节点从原链表中取下,按顺序改变next指针指向,组成新的链表,并恢复原链表的next指针
- 原链表中节点的数据拷贝
这一部分的实现代码如下:
Node* cur = head;
while(cur)
{
Node* copy = new Node(cur->val);//创造拷贝结点并拷贝数据
copy->next = cur->next;//插入过程
cur->next = copy;
cur = copy->next;//注意这里不是cur = cur->next;
}
2.原链表中节点的随机指针拷贝
随机指针不是单纯的拷贝,而是将拷贝节点的随机指针指向与原链表中关系对应的拷贝节点。
从原节点开始遍历,共分两种情况:若为当前结点cur的random为空则为空,cur的random的next是需被拷贝的新结点,当前结点的next的random是需修改的新结点。
这一部分的实现代码如下:
cur = head;//指针重置
while(cur)
{
Node* copy = cur->next;
if(cur->random == nullptr)//对指向NULL的情况额外处理
copy->random = nullptr;
else
{
copy->random = cur->random->next;//随机指针拷贝的关键
}
cur = copy->next;
}
3.原链表中节点的next指针拷贝,拷贝节点成为单独的新链表
这部分没什么好说的,采用新建头结点的形式来创建新链表,需要注意的是原链表的复原。
cur = head;//指针重置
Node* newhead = new Node(-1);//创造一个虚拟头节点
Node* ret = newhead; //头结点在变化,记录一下
while(cur)
{
Node* copy = cur->next;
newhead->next = copy;//链接头节点和copy结点
newhead = copy; //重新赋值头节点
cur->next = copy->next; //原链表的复原
cur = copy->next;
}
return ret->next;
完整代码 :
class Solution {
public:
Node* copyRandomList(Node* head) {
Node* cur = head;
while(cur)
{
Node* copy = new Node(cur->val);//创造拷贝结点
copy->next = cur->next;
cur->next = copy;
cur = copy->next;
}
cur = head;
while(cur)
{
Node* copy = cur->next;
if(cur->random == nullptr)
copy->random = nullptr;
else
{
copy->random = cur->random->next;
}
cur = copy->next;
}
cur = head;
Node* newhead = new Node(-1);
Node* ret = newhead;
while(cur)
{
Node* copy = cur->next;
newhead->next = copy;
newhead = copy;
cur->next = copy->next;
cur = copy->next;
}
return ret->next;
}
};