随机链表的深拷贝

news2024/11/23 0:12:41

目录

一、何为深拷贝?

二、题目

三、思路

1.拷贝节点插入到原节点后面

2.控制拷贝节点的random

3.脱离原链表 : 尾插的思想

四、代码

五、附加


一、何为深拷贝?

一个引用对象一般来说由两个部分组成:一个具名的Handle,也就是我们所说的声明(如变量)和一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增引用对象的New方法是进行创建。深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等。

简而言之:

深拷贝就是拷贝一个一摸一样的链表出来。

二、题目

给你一个长度为 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 作为传入参数。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

三、思路

1.拷贝节点插入到原节点后面


    while (cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));     //每次都要开辟空间     //强制类型转换!
        copy->val = cur->val;   //赋值
            //链接
        struct Node* next = cur->next;  //定义一个next指针,可不考虑顺序问题
        cur->next = copy;
        copy->next = next;

        cur = next;     //cur 指针在原链表往后走!

    } 

2.控制拷贝节点的random

关键:不为空,random->next = cur->random->next;为空,random->next = NULL;

while (cur)
    {
        struct Node* copy = cur->next;          //不需要额外开辟空间,copy节点已经连接了原节点

        if (cur->random == NULL)
            copy->random = NULL;

        else        //cur->random要注意是不是空!
            copy->random = cur->random->next;   //copy的random指向的是拷贝节点


            //迭代      //copy不需要迭代,copy是封装在循环内的指针,由cur控制!
        cur = copy->next;      //cur 在原链表迭代!
                    
    }

3.脱离原链表 : 尾插的思想

介绍尾插:用尾插的思想实现移除链表中的元素-CSDN博客

尾插不是插入到原链表的尾部,而是里用尾插的思想!tail是尾节点!而不是尾节点的下一个!

while (cur)
    {
        struct Node* copy = cur->next;
        
        //脱离

        if(CopyHead == NULL)
        {
            CopyHead = tail = copy;     //tail是尾节点!而不是尾节点的下一个!
        }

        else
        {
            tail->next = copy;
            tail = tail->next;  //tail是尾节点!而不是尾节点的下一个!
        }

        if(copy)
            cur = copy->next;   //其实也可以不需要判断copy是否为空!(链表节点总数是偶数,所以cur只会是偶节点,copy不会为空!)

    }

四、代码

 //没必要弄清原链表的random指针指向哪个节点,只需要弄清原理即可!
    // 需要注意:malloc开辟新空间

struct Node* copyRandomList(struct Node* head) {

    //1.拷贝节点插入到原节点后面、

    struct Node* cur = head;    //没有哨兵位!

    while (cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));     //每次都要开辟空间     //强制类型转换!
        copy->val = cur->val;   //赋值
            //链接
        struct Node* next = cur->next;  //定义一个next指针,可不考虑顺序问题
        cur->next = copy;
        copy->next = next;

        cur = next;     //cur 指针在原链表往后走!

    } 

    // 2.控制拷贝节点的random

    cur = head;     //重置cur
	
    while (cur)
    {
        struct Node* copy = cur->next;          //不需要额外开辟空间,copy节点已经连接了原节点

        if (cur->random == NULL)
            copy->random = NULL;

        else        //cur->random要注意是不是空!
            copy->random = cur->random->next;   //copy的random指向的是拷贝节点


            //迭代      //copy不需要迭代,copy是封装在循环内的指针,由cur控制!
        cur = copy->next;      //cur 在原链表迭代!
                    
    }


    //3.脱离原链表 : 尾插的思想
    cur = head;

    struct Node* CopyHead = NULL, *tail = NULL;

        //尾插的思想链接节点!
    while (cur)
    {
        struct Node* copy = cur->next;
        
        //脱离

        if(CopyHead == NULL)
        {
            CopyHead = tail = copy;     //tail是尾节点!而不是尾节点的下一个!
        }

        else
        {
            tail->next = copy;
            tail = tail->next;  //tail是尾节点!而不是尾节点的下一个!
        }

        if(copy)
            cur = copy->next;   //其实也可以不需要判断copy是否为空!(链表节点总数是偶数,所以cur只会是偶节点,copy不会为空!)

    }
 
    return CopyHead;

}

五、附加

头插也是一种常用的思想,常用来逆置,讲解如下:

题目:反转链表(头插与非头插)-CSDN博客

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

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

相关文章

cinder学习小结

1 官方文档 翻译官方文档学习 链接Cinder Administration — cinder 22.1.0.dev97 documentation (openstack.org) 1.1 镜像压缩加速 在cinder.conf配allow_compression_on_image_upload True可打开开关 compression_format xxx可设置镜像压缩格式&#xff0c;可为gzip 1.2 …

SPP和SPPF的比较

SPP的结构是将输入并行通过多个不同大小的MaxPool层&#xff0c;然后做进一步融合&#xff0c;能在一定程度上解决多尺度问题。 而SPPF结构则是讲输入串行通过多个5*5的MaxPool层&#xff0c;这里需要注意两个5*5的MaxPool层和一个9*9的MaxPool的计算结果是一样的&#xff0c;而…

[蓝桥杯 2022 省 A] 求和

[蓝桥杯 2022 省 A] 求和 题目描述 给定 n n n 个整数 a 1 , a 2 , ⋯ , a n a_{1}, a_{2}, \cdots, a_{n} a1​,a2​,⋯,an​, 求它们两两相乘再相加的和&#xff0c;即 S a 1 ⋅ a 2 a 1 ⋅ a 3 ⋯ a 1 ⋅ a n a 2 ⋅ a 3 ⋯ a n − 2 ⋅ a n − 1 a n − 2 ⋅ a…

3、创建项目,什么是路由

一、创建项目 第一次全局安装脚手架 npm install -g vue/clivue create 项目名 二、什么是路由&#xff1f; 路由就是一组 key-value 的对应关系多个路由&#xff0c;需要经过路由器的管理 1、后端路由&#xff1a; 每个url地址都对应着不同的静态资源对于普通的网站。所有…

记录整合ssm项目时的报错java: Compilation failed: internal java compiler error

启动的时候报错java: Compilation failed: internal java compiler error&#xff0c;这说明是内部编译器错误。如下图所示&#xff1a; 大概率是jdk版本不兼容的问题&#xff0c;也有IDEA初始划分的堆内存不够的原因。 查阅了很多博客的解决方法也都是上述两种&#xff0c;但…

C++引用学习day2

思维导图 定义一个矩形类&#xff08;Rectangle&#xff09;&#xff0c;包含私有成员&#xff1a;长(length)、宽&#xff08;width&#xff09;, 定义成员函数&#xff1a; 设置长度&#xff1a;void set_l(int l) 设置宽度&#xff1a;void set_w(int w) 获取长度&#…

vscode 配置c++环境——3个文件搞定!!!

前提&#xff1a; 在vscode中安装了c扩展 创建文件settings.json {"files.associations": {"string": "cpp","vector": "cpp","array": "cpp","atomic": "cpp","*.tcc"…

Springboot快速整合bootstrap-table使用,接口对接

这个表格加持还是不错了&#xff0c;自带了全局搜索&#xff0c;分页&#xff0c;数据导出&#xff0c;卡片视图&#xff0c;等&#xff0c;本次整合添加了数据添加弹窗和编辑数据回显弹窗&#xff0c;附完整页面代码&#xff0c;只需要拿过来替换自己实际的接口即可。 效果图 …

轻松掌握C语言中的sqrt函数,快速计算平方根的魔法秘诀

C语言文章更新目录 C语言学习资源汇总&#xff0c;史上最全面总结&#xff0c;没有之一 C/C学习资源&#xff08;百度云盘链接&#xff09; 计算机二级资料&#xff08;过级专用&#xff09; C语言学习路线&#xff08;从入门到实战&#xff09; 编写C语言程序的7个步骤和编程…

ES6 字符串/数组/对象/函数扩展

文章目录 1. 模板字符串1.1 ${} 使用1.2 字符串扩展(1) ! includes() / startsWith() / endsWith()(2) repeat() 2. 数值扩展2.1 二进制 八进制写法2.2 ! Number.isFinite() / Number.isNaN()2.3 inInteger()2.4 ! 极小常量值Number.EPSILON2.5 Math.trunc()2.6 Math.sign() 3.…

力扣hot100:207. 课程表

这是一道拓扑排序问题&#xff0c;也可以使用DFS判断图中是否存在环。详情请见&#xff1a;官方的BFS算法请忽略&#xff0c;BFS将问题的实际意义给模糊了&#xff0c;不如用普通拓扑排序思想。 数据结构&#xff1a;图的拓扑排序与关键路径 拓扑排序&#xff1a; class Sol…

详解:写作和赚钱的 4 个关系!看完你一定会忍不住想开始写!

飞书文档的加密很强&#xff0c;也没有和自家的豆包大模型融合&#xff0c;所以只能通过其他方式获取文档的内容。 &#xff08;1&#xff09;将飞书文档转换为PDF&#xff0c;要用到浏览器插件&#xff1a; GoFullPage - Full Page Screen Capture - Microsoft Edge Addons …

ElasticSearch启动报错:Exception in thread “main“ SettingsException

Exception in thread "main" SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]]; 这个报错说明elasticsearch.yml这个配…

垃圾回收:垃圾回收器

目录 垃圾回收器 评估GC的性能指标 7种典型的垃圾回收器 Serial回收器&#xff1a;串行回收 ParNew回收器&#xff1a;并行回收 Parallel回收器&#xff1a;吞吐量优先 CMS回收器&#xff1a;低延迟 G1回收器&#xff1a;区域化分代式 G1回收过程1-年轻代GC G1回收过程…

Java代码基础算法练习-报数问题-2024.03.26

任务描述&#xff1a; 有n个人围成一个圆圈分别编号1~n,从第1个到m循环报数&#xff0c;凡是报到m者离开&#xff0c;求n个 人离开圆圈的次序。 任务要求&#xff1a; 代码示例&#xff1a; package M0317_0331;import java.util.ArrayList; import java.util.List; import j…

档案室升级改造基建方面需要考虑哪些问题

升级和改造档案室可能需要以下材料&#xff1a; 1. 墙壁和地板材料&#xff1a;选择耐用、易于清洁的材料&#xff0c;如瓷砖、大理石、地板、木材或维护低的地毯等。 2. 墙体材料&#xff1a;可能需要新的墙壁材料来分隔出更多的空间&#xff0c;例如石膏板、砖块或玻璃隔断等…

基于RAG的大模型知识库搭建

什么是RAG RAG(Retrieval Augmented Generation)&#xff0c;即检索增强生成技术。 RAG优势 部分解决了幻觉问题。由于我们可以控制检索内容的可靠性&#xff0c;也算是部分解决了幻觉问题。可以更实时。同理&#xff0c;可以控制输入给大模型上下文内容的时效性&#xff0c…

【Java程序设计】【C00369】基于(JavaWeb)Springboot的笔记记录分享平台(有论文)

[TOC]() 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击…

PTA L2-034 口罩发放

为了抗击来势汹汹的 COVID19 新型冠状病毒&#xff0c;全国各地均启动了各项措施控制疫情发展&#xff0c;其中一个重要的环节是口罩的发放。 某市出于给市民发放口罩的需要&#xff0c;推出了一款小程序让市民填写信息&#xff0c;方便工作的开展。小程序收集了各种信息&…

【MySQL】数据库--库操作

目录 一、创建数据库 二、打开数据库 三、修改数据库 四、显示数据库 五、删除数据库 六、备份与恢复数据库 1.备份&#xff1a; 2.恢复&#xff1a; 一、创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] …] [DEF…