剑指offer35 复杂链表的复制

复杂链表的复制

题目

官方地址
在这里插入图片描述

代码

class Solution {
    public Node copyRandomList(Node head) {
        // 处理特殊情况,如果头节点为空,则返回null
        if (head == null) {
            return null;
        }

        // 第一步:构建一个组合链表
        Node cur = head;
        while (cur != null) {
            Node tmp = new Node(cur.val); // 创建一个新节点,值为当前节点的值
            tmp.next = cur.next; // 将新节点的next指针指向当前节点的下一个节点
            cur.next = tmp; // 将当前节点的next指针指向新节点,实现插入操作
            cur = tmp.next; // 更新当前节点为原节点的下一个节点
        }

        // 第二步:构建random指针
        cur = head;
        while (cur != null) {
            if (cur.random != null) {
                cur.next.random = cur.random.next; // 复制节点的random指针指向原节点的random指针的下一个节点
            }
            cur = cur.next.next; // 更新当前节点为原节点的下一个节点的下一个节点
        }

        // 第三步:拆分链表
        Node res = head.next; // 复制链表的头节点
        cur = head.next; // 当前节点指向复制链表的头节点
        Node pre = head; // 前一个节点指向原链表的头节点
        while (cur.next != null) {
            pre.next = pre.next.next; // 恢复原链表的next指针
            cur.next = cur.next.next; // 恢复复制链表的next指针
            pre = pre.next; // 更新前一个节点为原链表的下一个节点
            cur = cur.next; // 更新当前节点为复制链表的下一个节点
        }
        pre.next = null; // 单独处理最后一个节点,将其next指针设置为null

        // 返回复制链表的头节点
        return res;
    }
}

题解

在复制链表的过程中,我们需要处理每个节点的random指针。random指针指向链表中的任意节点或者null。为了正确复制random指针,我们需要遵循以下步骤:

  1. 第一步:复制节点并插入到原节点的后面。
    • 对于每个原节点,我们创建一个新节点,并将其插入到原节点的后面。这样原链表的结构就变成了:原节点 -> 新节点 -> 原节点的下一个节点。
  2. 第二步:设置复制节点的random指针。
    • 对于每个原节点,我们将新节点的random指针指向原节点的random指针的下一个节点。这是因为在第一步中,我们已经将新节点插入到了原节点的后面,所以新节点的位置就是原节点的下一个节点。
  3. 第三步:拆分链表,恢复原链表和复制链表。
    • 在第一步和第二步完成之后,我们得到了一个组合链表,其中原节点和复制节点交替出现。现在我们需要将组合链表拆分为原链表和复制链表。
    • 遍历组合链表,通过调整每个节点的next指针,将原链表和复制链表分离开来。
    • 最后返回复制链表的头节点作为结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会喷火的小火龙

你的鼓励是我最大的创作动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值