力扣hot100:138. 随机链表的复制(技巧,数据结构)

news2025/7/5 16:20:06

LeetCode:138. 随机链表的复制
在这里插入图片描述
这是一个经典的数据结构题,当做数据结构来学习。

1、哈希映射

需要注意的是,指针也能够当做unordered_map的键值,指针实际上是一个地址值,在unordered_map中,使用指针的实际内存地址值计算哈希函数,通过指针值来判断两个键值是否相等。

在第一次遇到这个问题时,最容易想到的方法自然是使用哈希表直接构造一模一样的。
遇到任何一个新结点直接构造,并用哈希表存储映射,然后依次遍历连接,每个遍历到的结点仅有可能被构造过,但不可能更新过nextrandom

使用哈希表:

  • 时间复杂度: O ( n ) O(n) O(n),其中n是链表的长度
    • 依次遍历,每个节点被遍历一次,每个节点被构造一次,每个节点被插入到哈希表一次,每个节点本身以及其后继和随机指向都在哈希表中被查找一次,平均查找和插入的速度为 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( n ) O(n) O(n),哈希表的空间
    在这里插入图片描述
class Solution {
public:
    Node* copyRandomList(Node* head) {
        unordered_map<Node *,Node *> mp;
        for(Node * p = head; p != nullptr; p = p->next){
            Node * nw;
            if(mp.count(p) == 0) {nw = new Node(p->val);mp[p] = nw;}//不重复构造,每个遍历到的结点p都需要更新next 和 random
            else nw = mp[p];
            
            if(p->next){//是否有后继
                if(mp.count(p->next) == 0){//后继是否被构造过
                    Node * nw_nex =  new Node(p->next->val); //如果没有的话,则构造并建立映射,连接后继
                    mp[p->next] = nw_nex;
                    nw->next = nw_nex;
                }
                else nw->next = mp[p->next];//有被构造过直接连接后继
            }
            if(p->random){
                if(mp.count(p->random) == 0){
                    Node * nw_random =new Node(p->random->val);
                    mp[p->random] = nw_random;
                    nw->random = nw_random;
                }
                else nw->random = mp[p->random];
            }
        }
        return mp[head];
    }
};
  • 当然直接遍历一次构建所有哈希映射,然后再连接会更简单,可以减少判断是否被构造过的情况,因为先建立之后一定被构造。
    • 这种方法只需要遍历两遍链表,每个结点进行一次哈希插入,以及进行其的后继和其随机指针进行一次哈希查找即可。

2、迭代 + 节点拆分(技巧性)

在这里插入图片描述第一遍遍历:拷贝结点,并将拷贝出的结点作为原结点的后继,拷贝后的结点的后继指向原结点的原始后继;
第二遍遍历:更新random
第三遍遍历:节点拆分,将拷贝出的结点和原始节点拆出来变成俩链。

你会发现,将拷贝结点作为原结点的后继,拷贝后的结点的后继指向原结点的原始后继并不影响原链表的遍历,因此这个方法是可行的。

这个方法拷贝的思想相当于先拷贝后继,将其放入到原始节点的后继。这并不会导致无法实现原链表的任何功能。然后再更新拷贝后的结点的信息,这时更新时所有原始链表的结点都已经被拷贝过一次,所有信息都可以直接使用。而不需要像方法一一样,顺序遍历更新,并不一定能保证random已经被创建出来,因此只能用哈希表存储

  • 时间复杂度: O ( n ) O(n) O(n),n是链表长度
    • 遍历一遍链表,拆分一次链表
  • 空间复杂度: O ( 1 ) O(1) O(1)
    在这里插入图片描述
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head) return head;
        //拷贝结点,更新后继
        Node * cur = head;
        while(cur){
			Node * nextNode = cur->next;
			cur->next = new Node(cur->val);
			cur->next->next = nextNode;
			cur = nextNode;
		}
		//更新random
		cur = head;
		while(cur){
			if(cur->random) cur->next->random = cur->random->next;//random可能为空
			cur = cur->next->next;
		}
		//节点拆分
		cur = head;
		Node * p = new Node(0);
		Node * result = p;
		while(cur){
			p->next = cur->next;
            p = p->next;
			cur->next = cur->next->next;
			cur = cur->next;
		}
		return result->next;
    }
};

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

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

相关文章

快速C++中的入门智能指针

✨前言✨ &#x1f4d8; 博客主页&#xff1a;to Keep博客主页 &#x1f646;欢迎关注&#xff0c;&#x1f44d;点赞&#xff0c;&#x1f4dd;留言评论 ⏳首发时间&#xff1a;2024年6月4日 &#x1f4e8; 博主码云地址&#xff1a;博主码云地址 &#x1f4d5;参考书籍&#…

【数据集划分】假如你有超百万条oracle数据库数据(成真版)

【数据集划分】假如你有接近百万条oracle数据库数据&#xff08;成真版&#xff09; 写在最前面小结 数据集划分原因注意事项 1. 留出法&#xff08;Hold-out Method&#xff09;原理算法复杂度代码示例Scikit-learn的train_test_split分布式计算框架&#xff08;如Apache Spar…

JVM学习-Jprofiler

JProfiler 基本概述 特点 使用方便&#xff0c;界面操作友好对被分析的应用影响小(提供模板)CPU&#xff0c;Tread&#xff0c;Memory分析功能尤其强大支持对jdbc,noSql,jsp,servlet,socket进行分析支持多种模式(离线、在线)的分析支持监控本地、远程JVM跨平台&#xff0c;拥…

MongoDB~索引使用与优化

Study by&#xff1a; https://docs.mongoing.com/indexeshttps://www.cnblogs.com/Neeo/articles/14325130.html#%E5%85%B6%E4%BB%96%E7%B4%A2%E5%BC%95 作用 如果你把数据库类比为一本书&#xff0c;那书的具体内容是数据&#xff0c;书的目录就是索引&#xff0c;所以索引…

C++第三方库【httplib】断点续传

什么是断点续传 上图是我们平时在浏览器下载文件的场景&#xff0c;下载的本质是数据的传输。当出现网络异常&#xff0c;浏览器异常&#xff0c;或者文件源的服务器异常&#xff0c;下载都可能会终止。而当异常解除后&#xff0c;重新下载文件&#xff0c;我们希望从上一次下载…

用例篇03

正交表 因素&#xff1a;存在的条件 水平&#xff1a;因素的取值 最简单的正交表&#xff1a;L4(2) 应用 allpairs 来实现正交表。 步骤&#xff1a; 1.根据需求找出因素和水平 2.将因素和水平写入到excel表格中&#xff08;表格不需要保存&#xff09;&#xff08;推荐用…

文本批量高效编辑器:一键在每行结尾添加分隔符,助力文本处理飞速提升!

在信息爆炸的时代&#xff0c;文本处理成为了一项不可或缺的技能。然而&#xff0c;面对大量的文本数据&#xff0c;如何高效地进行处理却成为了一项挑战。这时&#xff0c;一款高效、易用的文本批量编辑器就显得尤为重要。这个软件就是首助编辑高手 首先&#xff0c;打开首助…

fairseq框架使用记录

sh命令 cmd"fairseq-train data-bin/$data_dir--save-dir $save_dir--distributed-world-size $gpu_num -s $src_lang -t $tgt_lang--arch $arch--dropout $dropout--criterion $criterion --label-smoothing 0.1--task mmt_vqa--optimizer adam --adam-betas (0.9, 0.98…

高并发系统限流原理

短时间内巨大的访问流量&#xff0c;我们如何让系统在处理高并发的同时还能保证自身系统的稳定性&#xff1f;估计有人会说&#xff0c;增加机器就可以了&#xff0c;因为我的系统架构设计就是按照分布式思想进行架构设计的&#xff0c;所以可以只需要增加机器就可以解决问题了…

代码随想录算法训练营day41

题目&#xff1a;01背包理论基础、416. 分割等和子集 参考链接&#xff1a;代码随想录 动态规划&#xff1a;01背包理论基础 思路&#xff1a;01背包是所有背包问题的基础&#xff0c;第一次看到比较懵&#xff0c;完全不知道dp数据怎么设置。具体分析还是dp五部曲&#xff…

Vue3实战笔记(58)—从零开始掌握Vue3插槽机制,基础入门

文章目录 前言插槽基础入门总结 前言 不论是组件封装还是分析源码&#xff0c;实际开发中经常接触插槽&#xff0c;插槽是干什么用的呢&#xff1f;组件之间能够接收任意类型的 JavaScript 值作为 props&#xff0c;但组件要如何接收模板内容呢&#xff1f;在某些场景中&#…

openssl 常用命令demo

RSA Private Key的结构&#xff08;ASN.1&#xff09; RSAPrivateKey :: SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- …

k8s学习--ConfigMap详细解释与应用

文章目录 一 什么是configmapConfigMap 的好处ConfigMap 的限制 二.创建ConfigMap的4种方式1.在命令行指定参数创建2.在命令行通过多个文件创建3.在命令行通过文件提供多个键值对创建4.YAML资源清单文件创建 三 configmap的两种使用方法1.通过环境变量的方式传递给pod2.通过vol…

vue3+typescript 使用Codemirror

安装 // npm npm install codemirror-editor-vue3 codemirror^5.65.12// ts版 还需安装&#xff1a; npm install types/codemirror全局注册 修改main.ts&#xff1a; import { createApp } from vueimport App from ./App.vueimport { InstallCodemirro } from "code…

文件编码概念

文件的读取 open()函数&#xff1a; 打开一个已存在的文件&#xff0c;或者创建一个新文件 open(name,mode,encoding) name:是要打开的目标文件名的字符串&#xff08;可以包含文件所在的具体路径&#xff09; mode:设置打开文件的模式&#xff08;访问模式&#xff09;&am…

LabVIEW步进电机的串口控制方法与实现

本文介绍了在LabVIEW环境中通过串口控制步进电机的方法&#xff0c;涵盖了基本的串口通信原理、硬件连接步骤、LabVIEW编程实现以及注意事项。通过这些方法&#xff0c;用户可以实现对步进电机的精确控制&#xff0c;适用于各种自动化和运动控制应用场景。 步进电机与串口通信…

【Linux】信号(一)

信号我们将从信号产生&#xff0c;信号的保存&#xff0c;信号处理分别进行讲解~ 至少大思路是这样。开始之前还要进行一些基础知识的铺垫。 目录 从生活中提炼一些结论&#xff1a;信号概念的一些储备&#xff1a;信号产生&#xff1a;一、kill指令&#xff1a;二、键盘组合键…

[数据集][目标检测]轮胎检测数据集VOC+YOLO格式439张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;439 标注数量(xml文件个数)&#xff1a;439 标注数量(txt文件个数)&#xff1a;439 标注类别…

面试官:核心线程数为零时,线程池会处理任务吗?

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

Redis篇 list类型在Redis中的命令操作

list在redis基本的命令 一.基本命令1.lpush和range2.lpushx rpushx3.lpop rpop4.lindex linsert llen5.lrem6.ltrim lset7.blpop brpop 一.基本命令 list在redis中相当于数组或者顺序表. 1.lpush和range 2.lpushx rpushx 3.lpop rpop 4.lindex linsert llen 如果要插入的列表中…