面试经典150题——随机链表的复制

news2025/1/19 8:11:11

landscape photography of lake and mountain

前两天断更了两天有点事情🤗

1. 题目描述

image-20240310093647464

2.  题目分析与解析

2.1 思路一

开始还是没什么思路,没思路那就先把题目解决不管方法的好坏。如果不考虑复杂度,该怎么解决?

可以有这样的一种思路:

  1. 首先复制链表的所有节点,创造一个除了random全为空的相同链表

  2. 接下来按照每一个节点的random需要指向的位置,一个一个找到random指向的值,对random赋值

代码思路如下:

  1. 创建一个新的链表作为结果,一个指针指向结果链表的头部

  2. 遍历参数链表,复制一个一摸一样的链表

  3. 遍历参数链表,复制随机指针

  4. 返回结果链表

没想到还没有报超时:

image-20240314172831091

2.2 思路二——采用hash表

因为题目中只有一个random节点是格外需要注意的,那么我们就可以针对random节点怎么样想一种办法,根据思路一,让复制的链表在找random时能够最快的找到

因为如果要在找random时能够最快的找到,那么肯定是找引用,因为我们找的是一个Node对象。而结果链表和原始链表也肯定是对称的,也就是说原始链表的某一个节点的random指向某个节点,那么结果链表的对应节点的random也会指向对应的节点。所以难点就在于怎么样找到对应关系。

因此我们就可以想到定义一个<Node, Node>类型的结构,键作为原始链表的节点,值作为结果链表的节点。

先把所有的键都设置为原始链表的所有节点,那么键是不是也相当于构成了一个链表,对应的,我们再去对结果链表进行赋值。

  • 结果链表的某一个节点的next是不是就相当于原始链表的对应节点,也就是的next指向的的值?

  • 而random节点不也是对应的的random指向的的值?

所以我们可以有如下代码思路:

  1. 先创建一个哈希表,捆绑原始节点和新节点

  2. 遍历原始链表,更新新链表的next和random指针

  3. 返回新链表的头部

2.3 思路三——回溯 + 哈希表

引自作者:力扣官方题解

本题要求我们对一个特殊的链表进行深拷贝。如果是普通链表,我们可以直接按照遍历的顺序创建链表节点。而本题中因为随机指针的存在,当我们拷贝节点时,「当前节点的随机指针指向的节点」可能还没创建,因此我们需要变换思路。

一个可行方案是,我们利用回溯的方式,让每个节点的拷贝操作相互独立。对于当前节点,我们首先要进行拷贝,然后我们进行「当前节点的后继节点」和「当前节点的随机指针指向的节点」拷贝,拷贝完成后将创建的新节点的指针返回,即可完成当前节点的两指针的赋值。

具体地,我们用哈希表记录每一个节点对应新节点的创建情况。遍历该链表的过程中,我们检查「当前节点的后继节点」和「当前节点的随机指针指向的节点」的创建情况。如果这两个节点中的任何一个节点的新节点没有被创建,我们都立刻递归地进行创建。当我们拷贝完成,回溯到当前层时,我们即可完成当前节点的指针赋值。

注意一个节点可能被多个其他节点指向,因此我们可能递归地多次尝试拷贝某个节点,为了防止重复拷贝,我们需要首先检查当前节点是否被拷贝过,如果已经拷贝过,我们可以直接从哈希表中取出拷贝后的节点的指针并返回即可。

在实际代码中,我们需要特别判断给定节点为空节点的情况。

具体见后代码实现注释。其实这种思路和思路二是有点相似的,根据hashMap中的值来连接。

3.4 思路四——迭代 + 节点拆分

引自作者:力扣官方题解——我在代码中加了详细注释,看不懂题解可以直接看代码和动图

image-20240314210118271

recording

3. 代码实现

3.1 思路一

image-20240314173043930

image-20240314201440711

3.2 思路二

image-20240314201422107

image-20240314202232781

3.3 思路三

image-20240314205434543

image-20240314205344428

3.4 思路四

image-20240314211346947

image-20240314211357741

4. 相关复杂度分析

思路1

  • 时间复杂度: O(n²)。这种方法涉及到两次遍历原始链表。在复制随机指针时,对于每个节点都需要从头遍历链表以找到随机指向的节点,因此最坏情况下的时间复杂度为O(n²)。

  • 空间复杂度: O(1)。该方法仅使用了常数级别的额外空间(不考虑输出的空间),主要是几个临时变量。

思路2

  • 时间复杂度: O(n)。这种方法只需要遍历链表两次,一次用于复制节点并建立原节点和新节点之间的映射,另一次用于更新新链表中各节点的next和random指针。每次操作都可以在常数时间内完成,因此时间复杂度为O(n)。

  • 空间复杂度: O(n)。该方法需要一个HashMap来存储原节点与新节点之间的映射,最坏情况下需要存储n个键值对,因此空间复杂度为O(n)。

思路3

  • 时间复杂度: O(n)。通过递归的方式复制每个节点及其next和random指针。由于使用了哈希表来避免重复复制节点,确保每个节点只被复制一次,所以总的时间复杂度为O(n)。

  • 空间复杂度: O(n)。除了递归调用栈外,该方法同样需要一个HashMap来存储已经复制过的节点,以避免重复复制。最坏情况下,HashMap和递归栈的空间复杂度均为O(n)。

思路4

  • 时间复杂度: O(n)。该方法涉及三次遍历链表:一次用于在原节点后插入复制节点,一次用于更新所有新节点的random指针,最后一次用于拆分链表。每次遍历都可以在O(n)时间内完成。

  • 空间复杂度: O(1)。此方法在原始链表的基础上直接操作,不需要使用额外的空间来存储节点映射(忽略输出链表所占用的空间)。只使用了常数级别的额外空间,主要是几个用于遍历链表的临时变量。

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

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

相关文章

springboot271制造装备物联及生产管理ERP系统

制造装备物联及生产管理ERP系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装制造装备物联及…

C语言例:表达式(a=2,3),a+1的值

题目&#xff1a;设int a; 则表达式(a2,3),a1的值 #include<stdio.h> int main(void) {int a0;int b;int c;b (a2,4);c (a2,3),a1;printf("a1%d\n",a1); //a1 3;printf("a2,4的值为&#xff1a;%d\n",b); //a2,4的值为&…

【1】Python零基础起步

什么是编程(Programming) 编程是编定程序的中文简称&#xff0c;就是让计算机代码解决某个问题&#xff08;目的&#xff09;&#xff0c;对某个计算体系规定一定的运算方式&#xff0c;使计算体系按照该计算方式运行&#xff0c;并最终得到相应结果的过程&#xff08;手段&am…

Window11安装达梦数据库

由于现在流行国产化&#xff0c;很多公司的数据库产品都使用了国产数据库&#xff0c;所以&#xff0c;今天给大家讲解一下&#xff0c;达梦数据库的安装和试用&#xff0c;这样学完以后&#xff0c;就可以直接在公司里面用了。 首先&#xff0c;需要先注册账号&#xff0c;然…

#数据结构 线性表的顺序存储

目录 每日文案 一、线性表的定义 二、线性表的操作 顺序表的存储结构 顺序表的初始化操作 判断顺序表是否为空表 将顺序表置为空表 计算顺序表中的元素个数 取出顺序表中的对应位置元素 取出对应数值的位序 在对应位置插入元素 将对应位置的元素删除 将顺序表中的数据…

视觉系统对透明胶水的检测都有哪些方案?

透明胶水的检测在工业生产中是一个挑战&#xff0c;因为传统的基于RGB相机的视觉系统通常难以检测透明物体。然而&#xff0c;随着技术的发展&#xff0c;现在有多种方法可以有效地检测透明胶水。 1. 高光谱相机&#xff1a;高光谱相机可以提供不同于传统RGB相机的解决方案。例…

为什localhost被forbidden而127.0.0.1不被绊?

原因&#xff1a; 判段网关的时候判127.0.0.1&#xff0c;所以最好改localhost 其他参考&#xff1a; 【计算机网络】localhost不能访问&#xff0c;127.0.0.1可以访问&#xff1f;_ping localhost和ping 127.0.0.1-CSDN博客

【LeetCode每日一题】2312. 卖木头块(DFS记忆化搜索+动态规划)

文章目录 [2312. 卖木头块](https://leetcode.cn/problems/selling-pieces-of-wood/)思路1:用DFS进行记忆化搜索代码&#xff1a;思路2:动态规划代码&#xff1a; 2312. 卖木头块 思路1:用DFS进行记忆化搜索 1.要用DFS深度优先遍历每一种情况。在递归的同时&#xff0c;不断更…

了解什么是 Redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 Redis 的穿透?

目录 一、面试官心理分析 二、面试题剖析 1. 缓存雪崩 2. 缓存穿透 3. 缓存击穿 一、面试官心理分析 其实这是问到缓存必问的&#xff0c;因为缓存雪崩和穿透&#xff0c;是缓存最大的两个问题&#xff0c;要么不出现&#xff0c;一旦出现就是致命性的问题&#x…

WOA-GRU多输入时序预测 | 鲸鱼优化算法-门控循环单元神经网络 | Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&…

国产软件很流氓?这些良心之作,比你想象的更加强大

说到国产软件&#xff0c;大家可能首先会想到“流氓软件”、“捆绑安装”和“满屏广告”这些烦人的标签。直接上狠货&#xff0c;几款高质量软件&#xff0c;错过了&#xff0c;真可惜。 1、格式工厂 说起格式工厂&#xff0c;这款国产软件可谓是历史悠久&#xff0c;曾经陪伴…

AI程序员Devin会在6个方面影响人类程序员

讲动人的故事&#xff0c;写懂人的代码 初创公司Cognition最近所发布的世界上首个AI程序员Devin&#xff0c;让人类程序员百感交集。因为Devin能自动干下面的事情&#xff1a; 自己学习不熟悉的技术&#xff1b; 端到端地自己搭建和部署应用程序&#xff1b; 自己找出并修复…

YOLOv9实例分割教程|(二)验证教程

专栏地址&#xff1a;目前售价售价59.9&#xff0c;改进点30个 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 一、验证 打开分割验证文件&#xff0c;填入数据集配置文件、训练好的权重文件&…

【数据结构】二叉搜索树底层刨析

文章目录 1. 二叉搜索树的实现2. 二叉搜索树的应用3. 改造二叉搜索树为 KV 结构4. 二叉搜索树的性能分析 1. 二叉搜索树的实现 namespace key {template<class K>struct BSTreeNode{typedef BSTreeNode<K> Node;Node* _left;Node* _right;K _key;BSTreeNode(const…

基于ElasticSearch存储海量AIS数据:AIS数据索引机制篇

文章目录 引言I 预备知识1.1 索引结构1.2 AIS信息项II AIS数据索引2.1 AIS数据静态数据索引2.2 AIS数据动态信息索引2.3 引入静态信息的AIS数据轨迹信息索引引言 AIS数据信息根据其不同更新频率可分为静态和动态信息。索引结构设计包含了静态、动态和轨迹信息索引。同时,为了…

我记不住的那些命令-xxdod

背景&#xff1a; 这里记录一下具体的xxd和od命令参数和使用方法&#xff0c;我想我肯定是记不住这些参数的。 零、文件 我们这里有一个示例文件README.txt&#xff0c;内容如下图所示&#xff1a; 一、xxd(查看、编辑二进制文件) 1. 十六进制显示(默认) 我们发现上面的显…

【jQuery】一篇文章学会jQuery!

一、JavaScript与jQuery JavaScript&#xff08;简称JS&#xff09;是一种广泛应用的编程语言&#xff0c;主要用于网页开发。它是一种多才多艺、动态性强的语言&#xff0c;允许开发人员为网页应用添加交互性、操作文档对象模型&#xff08;DOM&#xff09;并创建丰富的用户体…

网络编程:TCP和UDP

一、通信模式 1.1 套接字socket 1.网络通信通过套接字进行数据传输 2.socket是一个函数&#xff0c;为通信创建一个端点&#xff0c;并返回该端点的文件描述符 3.套接字本身是一个文件描述符&#xff0c;对应的是一个特殊的文件&#xff0c;该文件描述符维护了两个缓冲区&a…

什么是分段锁?

1、典型回答 分段锁是一种将锁细化到每个段(Segment) 级别的锁设计。在 ConcurrentHashMap 中&#xff0c;它将整个数据结构分成多个段&#xff0c;每个段只锁定自己的一部分数据。每个段可以看作是一个独立的分组&#xff0c;只锁定该段(Segment)内部的数据操作&#xff0c;不…

以题为例浅谈SSRF

什么是ssrf SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。 一般情况下&#xff0c;SSRF攻击的目标是从外网无法访问的内部系统。&#xff08;正是因为它是由服务端发起的&#xff0c;所以它能够请求到与它相连…