随机链表的复制(图文解析)

138. 随机链表的复制

题目链接

在这里插入图片描述

思路:

  1. 完成节点数据拷贝——在原链表的每个节点后面增加一个拷贝节点,拷贝节点的值等于原节点的值
  2. 完成节点的随机指针拷贝——原节点的随机指针指向哪里,拷贝节点就指向对应节点的下一个节点(这一部分是这条思路能实现的关键)
  3. 完成节点的next指针拷贝——将拷贝节点从原链表中取下,按顺序改变next指针指向,组成新的链表,并恢复原链表的next指针
  1. 原链表中节点的数据拷贝

在这里插入图片描述

这一部分的实现代码如下:

        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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值