图解LeetCode——138. 复制带随机指针的链表

news2024/11/20 11:47:33

一、题目

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

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

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val】一个表示 Node.val 的整数。
random_index】随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

二、示例

2.1> 示例 1:

输入】head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出】[[7,null],[13,0],[11,4],[10,2],[1,0]]

2.2> 示例 2:

输入】head = [[1,1],[2,1]]
输出】[[1,1],[2,1]]

2.3> 示例 3:

输入】head = [[3,null],[3,0],[3,null]]
输出】[[3,null],[3,0],[3,null]]

提示:

  • 0 <= n <= 1000
  • -10^4 <= Node.val <= 10^4
  • Node.random 为 null 或指向链表中的节点。

三、解题思路

3.1> 思路1:利用哈希表

根据题目描述,如果仅仅是单向链表,我们可以非常方便的通过在遍历旧的链表的同时来构建新的链表,但是本题中的一个难点是,存在一个属性是Node random,它用来表示随机的一个指针,执行链表中的任意节点,甚至是空节点。所以,针对这种特性,我们比较容易想到的一个解题思路就是借用哈希表来实现解题,其中:

key】保存旧的链表节点;
value】保存新建的链表节点;

这样,我们就可以通过两次遍历旧的链表来解答这道题的,逻辑如下所示:

第1次遍历旧链表】将遍历的旧节点保存到key中,将新建的节点保存到value中;
第2次遍历旧链表】通过遍历旧节点的random节点寻找新建的random节点,并赋值给新的节点中;

以上就是解题思路,因为逻辑比较容易理解,所以此处就不画图了。

3.2> 思路2:原链表新建节点

除了上面利用哈希表的解题方式之外,我们其实可以不借助额外的容器来解题的。那么,在思路2中,我们就是采用在原有链表修改的方式进行解题的。为了便于描述,我们会以下面的链表为例:

本解题思路一共有如下3个步骤:

步骤1】遍历旧的链表,每当遍历一个旧节点时,就在该节点的后面复制一个全新的节点,但是此时新节点中random是没有值的;
步骤2】再次遍历旧的链表,由于相同新旧两个节点是相邻的,所以我们可以得出一个规律,即:旧节点的random节点一定与新节点的random节点相邻。所以,我们以Node(3)为例,新的Node(3)的random就是旧的Node(3).random.next
步骤3】我们拆分新旧链表,这样,返回新链表的头节点即可;

如上就是思路2的解题思路了,为了方便大家理解,我们下面还是以图解的方式演示一下这3个步骤的操作方式。请见下图所示:

四、代码实现

4.1> 实现1:利用哈希表

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return head;
        Map<Node, Node> map = new HashMap();
        Node p1 = head, temp = new Node(-1), p2 = temp;
        while (p1 != null) {
            map.put(p1, new Node(p1.val));
            p1 = p1.next;
        }
        p1 = head;
        while (p1 != null) {
            Node node = map.get(p1);
            node.random = map.get(p1.random);
            p2.next = node; 
            p1 = p1.next;
            p2 = p2.next;
        }
        return temp.next;
    }
}
/*
// 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;
    }
}
*/

4.2> 实现2:原链表新建节点

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return head;
        Node temp = null, node = null;
        // 步骤1:复制新节点
        Node p1 = head;
        while (p1 != null) {
            temp = p1.next;
            node = new Node(p1.val);
            p1.next = node;
            node.next = temp;
            p1 = temp;
        }
        // 步骤2:关联random指针
        Node p2 = head;
        while (p2 != null) {
            p2.next.random = (p2.random == null) ? null : p2.random.next;
            p2 = p2.next.next;
        }
        // 步骤3:拆分出新的链表
        Node nhead = new Node(-1), p3 = head, p4 = nhead;
        while(p3 != null) {
            p4.next = p3.next;
            p4 = p3.next;
            p3.next = p3.next.next;
            p3 = p3.next;
        }
        return nhead.next;
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/568754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

研报精选230525

目录 【行业230525中泰证券】半导体行业深度报告&#xff1a;解析英伟达成长的核心战略&#xff1a;研发为底、生态为径、AI为翼 【行业230525西南证券】医药行业周报&#xff1a;行情回暖&#xff0c;持续精选个股 【行业230525国元证券】2023年中期军工行业投资策略&#xff…

2023最系统的网络安全学习路线

什么是网络安全 网络安全是指保护计算机网络及其系统和应用程序的安全性和完整性&#xff0c;防止未经授权的访问、攻击、病毒、恶意软件和其他安全威胁。它是通过技术、管理和教育等综合手段来确保网络信息安全。网络安全包括网络防火墙、入侵检测系统、数据加密、网络访问控…

STM8、STM8S003F3P6 双机串口通信(片上串口)

背景 这里为什么要写串口通信&#xff0c;因为实际项目上使用了串口&#xff0c;STM8S003F3P6的串口简单啊&#xff0c;不值得一提。本文写的串口确实简单&#xff0c;因为这里我想先从简单的写起来&#xff0c;慢慢的把难的引出来。这里呢&#xff0c;做个提纲说明&#xff0…

基于SSM+HTML5的网上跳蚤市场系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;HTML 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 前言…

数据结构-查找(顺序查找与二分查找的讲解与代码实现)

顺序查找概念&#xff1a;从表的另一端开始&#xff0c;一次将记录的关键字和给定值进行比较&#xff0c;若某个记录的关键字和给定的值相等&#xff0c;则查找成功&#xff0c;反之则查找失败。 ASL:平均查找长度 pi查找概率&#xff0c;ci查找次数 eg&#xff1a;序列1&…

kubelet源码分析 status_manager状态管理器篇

kubelet源码分析 status_manager状态管理器篇 右上方的statusManager就是本篇要介绍的内容。上一篇kubelet的sync同步函数也介绍过&#xff0c;这篇内容详细介绍状态管理器的作用。 一、简介 status_manager&#xff08;状态管理器&#xff09;是 Kubernetes 中的一个组件&am…

【ONE·C++ || 哈希(二)】

总言 主要介绍哈希运用于unordered系列的上层封装框架与相关运用&#xff1a;位图、布隆过滤器、哈希切割。 文章目录 总言0、思维导图3、封装3.1、基础封装3.1.1、框架结构3.1.2、Inset 1.0 3.2、引入迭代器3.2.1、在迭代器中3.2.2、在哈希表中3.2.3、在unordered上层3.2.4、…

springBoot搭建

这里写目录标题 一、在学习spring Boot之前我们来回顾一下Spring二、Spring Boot介绍 三、Spring Boot开发环境搭配四、Spring Boot核心五、Spring Boot添加模块六、Spring Boot新注解介绍 一、在学习spring Boot之前我们来回顾一下Spring 首先说一下spring的优点: spring是轻…

Wireshark 解密https 数据

默认情况下 wireshark 抓到的https 数据包都是加密后的&#xff0c;无法展示明文内容 方式一 -SSLKEYLOGFILE 变量方式 【推荐&#xff0c;适用各种情况】 配置环境变量 浏览器在访问https 站点的时候会检测这个SSLKEYLOGFILE 变量&#xff0c;如果存在&#xff0c;则将https…

SpringCloud Nacos实战应用

目录 1 Nacos安装1.1 Nacos概要1.2 Nacos架构1.3 Nacos安装1.3.1 Nacos Derby安装1.3.2 Nacos MySQL版安装1.3.3 Docker 安装Nacos 2 Nacos功能应用2.1 Nacos服务注册与发现2.2 负载均衡2.3 配置中心2.4 灰度发布 3 Nacos集群3.1 集群架构3.2 Nacos集群部署3.3 客户端接入Nacos…

c# 依赖注入

依赖注入 文章目录 依赖注入一、.net core主要提供了三种依赖注入的方式二、权重三、如果我们需要注入的对象很多怎么办 一、.net core主要提供了三种依赖注入的方式 AddTransient瞬时模式&#xff1a; 每次请求&#xff0c;都获取一个新的实例。即使同一个请求获取多次也会是…

2022年度互联网平均薪资出炉!高到离谱!

近期&#xff0c;国家统计局发布2022年平均工资数据&#xff0c;互联网行业薪资再次成为大家关注的焦点。 在2022年分行业门类分岗位就业人员年平均工资中&#xff0c;信息传输、软件和信息技术服务业的薪资遥遥领先其他行业&#xff0c;为全国平均薪资水平的 1.78 倍&#xf…

devfreq

devfreq 是指频率电源可以动态调节的设备&#xff0c;可以添加不同设备及不同govvernor ; devfreq 框架和opp(operating performance point) 频率电源对 devices driver 通过 devfreq profile 交互 devfreq_dev_profile include/linux/devfreq.h devfreq_governor 与 dev…

如何用二极管实现不同电压的输出?

利用二极管的单向导电性可以设计出好玩、实用的电路。本文分析限幅电路和钳位电路&#xff0c;是如何用二极管来实现的。 限幅电路 如下图所示&#xff0c;当在正半周期&#xff0c;并且VIN大于等于0.7V&#xff0c;二极管正向导通。此时&#xff0c;VOUT会被钳位在0.7V上。 …

C++11:右值引用 -- 移动构造和移动赋值

目录 一. 左值引用和右值引用的概念和性质 1.1 什么是左值引用和右值引用 1.2 左值引用和右值引用的性质 二. 移动构造和移动赋值 2.1 左值引用的缺陷 2.2 临时对象返回减少拷贝的问题&#xff08;移动构造和移动赋值&#xff09; 2.3 C11 STL容器接口的一些变化 三. 完…

【C++进阶之路】手把手教你使用string类的接口

文章目录 前言基本认识基本使用 一.构造函数默认构造函数拷贝构造函数其它构造函数①string(const char* s)②string(size_t n, char c)③string (const string& str, size_t pos, size_t len npos) 二.容量接口①size与length②max_size③capacity④empty⑤clear⑥revers…

Elastic Learned Sparse Encoder 简介:Elastic 用于语义搜索的 AI 模型

作者&#xff1a;Aris Papadopoulos, Gilad Gal 寻找意义&#xff0c;而不仅仅是文字 我们很高兴地与大家分享&#xff0c;在 8.8 中&#xff0c;Elastic 提供开箱即用的语义搜索。语义搜索旨在根据文本的意图或含义进行搜索&#xff0c;而不是词汇匹配或关键字查询。与传统的…

华为云服务器租用费用及CPU性能(1核2G/2核4G/4核8G)

华为云HECS云服务器即云耀云服务器&#xff0c;类似于阿里云和腾讯云的轻量应用服务器&#xff0c;HECS云服务器1核2G配置39.02元一年、2核4G配置99元一年、4核8G配置69.94元3个月&#xff0c;华为云百科分享华为云HECS云服务器租用费用及CPU性能详解&#xff1a; 目录 华为云…

图解LeetCode链表题

&#x1f490;文章导读 本篇文章主要详细的用图解的方式为大家讲解了简单程度的链表题&#xff0c;如果题中有错误的地方&#xff0c;还麻烦您在评论区指出&#xff0c;你的意见就是我最大的进步&#xff01;&#xff01;&#xff01; &#x1f490;专栏导读 &#x1f934;作者…

什么是数字化?企业为什么要数字化转型

一、什么是数字化&#xff1f; 什么是数字化&#xff1f;在我理解&#xff0c;数字化是一个基于时代科技发展所产生的概念&#xff0c;首先它是一个工具&#xff0c;在企业的经营发展中将信息技术融入到传统的企业模式中&#xff0c;起到了转型的作用。 其次数字化转型是企业…