【Leetcode Top 100】138. 随机链表的复制

问题背景

给你一个长度为 n n n 的链表,每个节点包含一个额外增加的随机指针 r a n d o m random random,该指针可以指向链表中的任何节点或空节。

构造这个链表的 深拷贝 。 深拷贝应该正好由 n n n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 n e x t next next 指针和 r a n d o m random random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点

例如,如果原链表中有 X X X 和 Y Y Y 两个节点,其中 X . r a n d o m = Y X.random = Y X.random=Y。那么在复制链表中对应的两个节点 x x x 和 y y y,同样有 x . r a n d o m = y x.random = y x.random=y。

返回复制链表的头节点。

数据约束

  • 0 ≤ n ≤ 1000 0 \le n \le 1000 0≤n≤1000
  • − 1 0 4 ≤ N o d e . v a l ≤ 1 0 4 -10 ^ 4 \le Node.val \le 10 ^ 4 −104≤Node.val≤104
  • N o d e . r a n d o m Node.random Node.random 为 n u l l null null 或指向链表中的节点。

解题过程

经典链表操作题,解决的关键在于能否想到把新建的复制节点添加到原节点的后一个。

通过上述方案复制完整个链表之后,只要能够分离链表即可,参考 奇偶链表,本题中由于原链表的后一个节点是它本身的复制,一定存在,分离的时候可以少一个判断。

注意数据范围,头节点可能为空,要单独处理。

具体实现

java 复制代码
/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/

class Solution {
    public Node copyRandomList(Node head) {
        // 特判头节点为空的情形
        if(head == null) {
            return null;
        }
        // 在原链表的每个节点之后新建复制节点
        Node cur = head, next;
        while(cur != null) {
            next = cur.next;
            cur.next = new Node(cur.val, cur.next); // 题中没说明这个构造器,实际上是存在的
            cur.next.next = next;
            cur = cur.next.next;
        }
        // 重置工作指针
        cur = head;
        // 给每个新节点的随机域赋值
        while(cur != null) {
            if(cur.random != null) {
                cur.next.random = cur.random.next;
            }
            cur = cur.next.next;
        }
        // 分离原链表和复制之后的链表
        Node copyHead = head.next, copy;
        cur = head;
        while(cur.next.next != null) {
            copy = cur.next; // 记录下一个节点
            cur.next = cur.next.next; // 调整原链表的 next 指针
            copy.next = copy.next.next; // 调整新链表的 next 指针
            cur = cur.next; // 后移工作指针
        }
        // 原链表的最后一个节点要指空
        cur.next = null;
        return copyHead;
    }
}
相关推荐
JAVA学习通6 分钟前
零基础OSS组件(Java)
java·linux·leetcode
Python智慧行囊7 分钟前
图像处理(三)--开运算与闭运算,梯度运算,礼帽与黑帽
人工智能·算法·计算机视觉
前端小L9 分钟前
动态规划的“细节魔鬼”:子序列 vs 子数组 —— 最长重复子数组
算法·动态规划
草莓熊Lotso10 分钟前
《算法闯关指南:优选算法--二分查找》--19.x的平方根,20.搜索插入位置
java·开发语言·c++·算法
杨福瑞14 分钟前
C语言数据结构:算法复杂度(1)
c语言·开发语言·数据结构
sali-tec17 分钟前
C# 基于halcon的视觉工作流-章46-不匀面划痕
人工智能·算法·计算机视觉·c#
yuniko-n1 小时前
【力扣 SQL 50】连接
数据库·后端·sql·算法·leetcode
胖咕噜的稞达鸭1 小时前
算法入门:专题二---滑动窗口(长度最小的子数组)更新中
c语言·数据结构·c++·算法·推荐算法
海洲探索-Hydrovo6 小时前
TTP Aether X 天通透传模块丨国产自主可控大数据双向通讯定位模组
网络·人工智能·科技·算法·信息与通信
_OP_CHEN7 小时前
C++基础:(十二)list类的基础使用
开发语言·数据结构·c++·stl·list类·list核心接口·list底层原理