单链表OJ题:LeetCode--138.复制带随即指针的链表
朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中第138道单链表OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!
数据结构与算法专栏:数据结构与算法
个 人 主 页 :stackY、
C 语 言 专 栏:C语言:从入门到精通
LeetCode--138.复制带随即指针的链表:https://leetcode.cn/problems/copy-list-with-random-pointer/description/
目录
1.题目介绍
2.实例演示
3.解题思路
::链接拷贝结点 ::
::找拷贝节点的random ::
:: 拆解拷贝链表 ::
1.题目介绍
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
小编现在这里向大家袒露心扉一下:其实我刚刚看到这个单链表OJ题,看了半天连题目都没咋搞明白,好不容易看懂了题目介绍,可是又不知道该从何下手,然后求助各种大佬,才慢慢理解,然后整理思路,在这篇文章中将这道题分享给大家。
2.实例演示
3.解题思路
这道题应该算是单链表OJ题中比较复杂的一道题了,主要是比较难理解。题目的主要意思就是要拷贝出与原链表一模一样的一个链表。那么这道题拷贝链表都不是很复杂,比较难处理的就是这个随即指针random的指向,如果原链表的random指向空那这好说,拷贝链表的也指向空,但是如果原链表的random指向非空,那该如何去找这个random呢?在这里呢,很多老铁喜欢用random指向的值来比较,这种想法可以,但是架不住链表中有相同的值,那么就有许多老铁用它的random指向的地址来比较,这种方法是完全可行的,但是呢,这种暴力求解的方法往往都不是最优解,使用地址来进行比较的话它的时间复杂度是O(N^2),效率也是不太行。所以我们需要寻求更优解。
这道题的解题思路我分为了三个步骤:
1. 链接拷贝结点:
将拷贝结点插入到原结点的后面。
2. 找拷贝节点的random:
通过原链表来控制拷贝结点的随机指针random。
3. 拆解拷贝链表:
将拷贝结点拆下来,依次尾插组成新的链表,然后恢复原链表。
接下来我们一步一步来进行解题:
::链接拷贝结点 ::
我们可以将拷贝结点链接在原结点的后面,这种方法比较巧妙,有助于我们找随即指针random。
先创建拷贝节点,然后遍历原链表,然后保存头节点的下一个结点,改变指向,将拷贝节点插入到原结点的后面。
图示:
代码演示:
/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;//1.链接拷贝节点while(cur){//创建拷贝结点struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;//保存头指针的下一个结点struct Node* curNext = cur->next;//链接cur->next = copy;copy->next = curNext;cur = curNext;}//...... }
::找拷贝节点的random ::
当我们将拷贝结点链接在原结点的后面时,我们需要找拷贝结点的随机指针random,这里可以分为两种情况:
1. 如果原结点的random是空,那么直接将拷贝结点的random置为空即可。
2. 若不为空,那么就需要观察一下这个链表,拷贝结点的random指针指向的就是原结点的random指向的结点的next结点:
copy -> random = cur -> random -> next;
因为我们将拷贝结点链接在了原结点的后面,那么原结点的random指向的结点的next结点就是拷贝结点要找的random。我们依旧遍历整个链表,然后将拷贝节点的随机指针链接。
图示:
代码演示:
/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;//1.链接拷贝节点while(cur){//创建拷贝结点struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;//保存头指针的下一个结点struct Node* curNext = cur->next;//链接cur->next = copy;copy->next = curNext;cur = curNext;}//2.找拷贝节点的random //重新返回头cur = head;while(cur){//找拷贝结点struct Node* copy = cur->next;//找下一个结点struct Node* next = copy->next;//链接拷贝节点的随机指针randomif(cur->random == NULL){copy->random = NULL;}else{copy->random = cur->random->next;}//遍历cur = next;}//...... }
:: 拆解拷贝链表 ::
我们找到了拷贝链表之后呢,需要将这些拷贝的结点组成一个新的链表,这就需要将这些拷贝结点依次进行尾插,然后再将原链表恢复。这就比较简单了:
图示:
完整代码演示:
/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;//1.链接拷贝节点while(cur){//创建拷贝结点struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;//保存头指针的下一个结点struct Node* curNext = cur->next;//链接cur->next = copy;copy->next = curNext;cur = curNext;}//2.找拷贝节点的random //重新返回头cur = head;while(cur){//找拷贝结点struct Node* copy = cur->next;//找下一个结点struct Node* next = copy->next;//链接拷贝节点的随机指针randomif(cur->random == NULL){copy->random = NULL;}else{copy->random = cur->random->next;}//遍历cur = next;}//3.拆解拷贝结点,恢复原链表//重新返回头cur = head;//创建新的链表struct Node* copyHead = NULL;struct Node* copyTail = NULL;while(cur){//找拷贝结点struct Node* copy = cur->next;//找下一个结点struct Node* next = copy->next;//尾插拷贝节点构成新的链表if(copyTail == NULL){copyHead = copyTail = copy;}else{copyTail->next = copy;copyTail = copyTail->next;}//恢复原链表cur->next = next;cur = next;}return copyHead;}
朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!
相关文章:

单链表OJ题:LeetCode--138.复制带随即指针的链表
朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中第138道单链表OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏:数据结构与算法 个 人…...

Chapter7: SpringBoot与数据访问
尚硅谷SpringBoot顶尖教程 1. JDBC 1.1 依赖及配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency><groupId>mysql</groupId…...
【Sqlite3】maraidb和sqlite3部分命令操作区别
maraidb和sqlite3部分命令操作区别记录 1.安装sqlite3 在实现我的视频点播系统项目时,我尝试封装了两种数据库的调用逻辑 mysql(maraidb)sqlite3 这里封装sqlite3的原因是,sqlite3主要针对的就是嵌入式数据库,其性能…...

Linux中新建用户使用sudo问题
文章目录 sudo问题 sudo问题 sudo:权限提示指令,当使用sudo这条指令时,会将普通用户的权限提升为root权限 但是在命令行新建用户,这个用户使用sudo指令对一条指令提权是用不了的 这个用户没有在sudoers file这个文件中ÿ…...

Sentinel源码分析-ProceesorSlotChain调用链及树状资源节点
Sentinel 实现流控,隔离,降级等功能,本质要做两件事: 数据统计: 统计某个资源的访问数据(QPS,RT(响应时间),异常比例)等信息规则判断: 判断流控规…...

springboot 连接 kafka集群(kafka版本 2.13-3.4.0)
springboot 连接 kafka集群 一、环境搭建1.1 springboot 环境1.2 kafka 依赖 二、 kafka 配置类2.1 发布者2.1.1 配置2.1.2 构建发布者类2.1.3 发布消息 2.2 消费者2.2.1 配置2.2.2 构建消费者类2.2.3 进行消息消费 一、环境搭建 1.1 springboot 环境 JDK 11 Maven 3.8.x spr…...

Nacos配置中心使用(Spring Cloud版)
目标 向项目中集成Nacos配置。原项目是一个SpringBoot项目。这里假设我们无法修改原有项目的SpringBoot版本。 注意 在不动SpringBoot版本的前提下,根据SpringBoot的版本,确定Spring Cloud和Nacos版本。Nacos版本其实就是Spring Cloud Alibaba版本。在…...

STM32F407硬件I2C实现MPU6050通讯(CUBEIDE)
STM32F407硬件I2C实现MPU6050通讯 文章目录 STM32F407硬件I2C实现MPU6050通讯cubeide设置写操作与读操作函数实现复位,读取温度,角度等函数封装mpu6050.cmpu6050.h代码分析 DMP移植1.修改头文件路径为自己的头文件路径2.修改I2C读写函数为自己mcu平台的读…...

HTML5 语义元素(一)页面结构
本篇主要介绍HTML5增加的语义元素中关于页面结构方面的,包含: <article>、<aside>、<figure>、<figcaption>、<footer>、<header>、<main>、<nav>、<section>等元素。 目录 1. 语义元素介绍 1.…...

嵌套滚动实践:onInterceptTouchEvent与NestedScrolling【实用为准】
嵌套滚动:内外两层均可滚动,比如上半部分是一个有限的列表,下半部分是WebView,在内层上半部分展示到底的时候,外部父布局整体滚动内部View,将底部WevView拉起来,滚动到顶部之后再将滚动交给内部…...

Redis入门 - 5种基本数据类型
原文首更地址,阅读效果更佳! Redis入门 - 5种基本数据类型 | CoderMast编程桅杆https://www.codermast.com/database/redis/five-base-datatype.html 说明 在我们平常的业务中基本只会使用到Redis的基本数据类型(String、List、Hash、Set、…...

mybatis-plus用法(一)
MyBatis-plus 是一款 Mybatis 增强工具,用于简化开发,提高效率。下文使用缩写 mp来简化表示 MyBatis-plus,本文主要介绍 mp 整合 Spring Boot 的使用。 (5条消息) mybatis-plus用法(二)_渣娃工程师的博客-CSDN博客 1…...
源码安装包管理
1. 源码包基本概述 在linux环境下面安装源码包是比较常见的, 早期运维管理工作中,大部分软件都是通过源码安装的。那么安装一个源码包,是需要我们自己把源代码编译成二进制的可执行文件。 源码包的编译用到了linux系统里的编译器,通常源码包…...
Vue|获取表单数据
在Vue中获取表单数据有多种方式,具体取决于你使用的是哪种表单元素和你的需求。 1. 单个表单元素: 如果你只需要获取单个表单元素的值,可以使用v-model指令将表单元素的值绑定到Vue实例的一个属性上。例如: <input type&quo…...

微信小程序入门学习02-TDesign中的自定义组件
目录 1 显示文本2 自定义组件3 变量定义4 值绑定总结 我们上一篇讲解了TDesign模板的基本用法,如何开始阅读模板。本篇我们讲解一下自定义组件的用法。 1 显示文本 官方模板在顶部除了显示图片外,还显示了一段文字介绍。文字是嵌套在容器组件里…...

【linux kernel】linux media子系统分析之media控制器设备
文章目录 一、抽象媒体设备模型二、媒体设备三、Entity四、Interfaces五、Pad六、Link七、Media图遍历八、使用计数和电源处理九、link设置十、Pipeline和Media流十一、链接验证十二、媒体控制器设备的分配器API 本文基于linux内核 4.19.4,抽象媒体设备模型框架的相…...

Scala--03
第6章 面向对象 Scala 的面向对象思想和Java 的面向对象思想和概念是一致的。 Scala 中语法和 Java 不同,补充了更多的功能。 6.1类和对象详解 6.1.1组成结构 构造函数: 在创建对象的时候给属性赋值 成员变量: 成员方法(函数) 局部变量 代码块 6.1.2构造器…...
【MongoDB】--MongoDB高级功能
目录 一、前言二、聚合管道aggregate1、示例说明2、具体代码实现一、前言 这里主要记录mongodb一些高级功能使用,如聚合。 二、聚合管道aggregate 聚合操作将来自多个文档的值组合在一起,并且可以对分组数据执行各种操作以返回单个结果,主要用于处理数据(诸如统计平均值,…...
C# new与malloc
目录 C# new与malloc C# new与malloc的区别 C# new关键字底层做的操作 C# new与malloc new关键字: new关键字在C#中用于实例化对象,并为其分配内存。它是面向对象编程的基本操作之一。使用new关键字可以在托管堆上分配内存,同时调用对象的构…...

微软MFC技术简明介绍
我是荔园微风,作为一名在IT界整整25年的老兵,今天来看一下微软MFC技术简明介绍 Visual C 与 MFC 微软公司于1992年上半年推出了C/C 7.0 产品时初次向世人介绍了MFC 1.0,这个产品包含了20,000行C原始代码,60个以上的Windows相关类…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...