随机链表的深拷贝

目录

一、何为深拷贝?

二、题目

三、思路

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博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一键跳过开屏广告,这下舒服了

现在的app开屏广告越来越过分了&#xff0c;不小心摇一摇翻转就点开广告了。 今天分享个强大的自动跳过广告https://github.com/gkd-kit/gkd&#xff0c;李跳跳替代品&#xff0c;下载地址在公众号后台对话框回复 广告 玩转互联网达人 苏生不惑备用号&#xff0c;分享各种黑科…

初探Notion安装与使用

笔记工具哪家强&#xff0c;有道云笔记&#xff0c;印象笔记&#xff0c;记事本&#xff0c;notion 第一步、下载与安装 本次选择是window版本&#xff0c;下载地址【Notion官网】 版本为Notion Setup 3.3.0&#xff0c;软件大小74.3M&#xff0c;官网如下图所示。 进入登录…

159.乐理基础-和声模板是什么?优缺点与运用要点

如果到这五线谱还没记住还不认识的话去看102.五线谱-高音谱号与103.五线谱-低音谱号这两个里&#xff0c;这里面有五线谱对应的音名&#xff0c;对比着看 如果一章没落下&#xff0c;看到这里&#xff0c;但是看不懂什么意思&#xff0c;那就强行下看&#xff0c;看着看着指不…

第一个C++程序,我也没看明白,暂时。

#include<iostream> using namespace std; int main() { cout << "hello world and you too number!" << endl; system("pause"); return 0; } 运行结果为&#xff1a;

编程语言|C语言——C语言实现玫瑰花(情人节)

1.说明 在古希腊神话中&#xff0c;玫瑰花集爱与美于一身&#xff0c;既是美神的化身&#xff0c;又溶进了爱神的血液&#xff0c;所以它所代表的含义是爱情。 我们应该用玫瑰花来表达我们的爱意&#xff0c;但是好多的恋人都是因为异地而没有办法去买一束新鲜的玫瑰去送给自己…

MySql实战--深入浅出索引(上)

提到数据库索引&#xff0c;我想你并不陌生&#xff0c;在日常工作中会经常接触到。比如某一个SQL查询比较慢&#xff0c;分析完原因之后&#xff0c;你可能就会说“给某个字段加个索引吧”之类的解决方案。但到底什么是索引&#xff0c;索引又是如何工作的呢&#xff1f;今天就…

java高级面试题整理 - 2024

Java 创建对象有几种方式 在Java中&#xff0c;有以下几种常见的方式来创建对象&#xff1a; 使用new关键字&#xff1a;这是最常见的创建对象的方式。通过调用类的构造函数&#xff0c;使用new关键字可以在内存中分配一个新的对象。使用反射&#xff1a;Java的反射机制允许在…

HTML(二)---【常见的标签使用】

零.前言 本文只介绍常见的标签使用&#xff0c;其中使用的一些HTML专业术语可以在作者的第一篇文章&#xff1a; HTML&#xff08;一&#xff09;---【基础】-CSDN博客中找到。 一.<b>粗体、<i>或<em>斜体 1.定义 粗体、斜体的实现可以在CSS中实现&…

Linux网络协议栈从应用层到内核层③

文章目录 1、write源码剖析2、vfs层进行数据传输3、socket层进行数据传输4、tcp层进行数据传输5、ip层进行数据传输6、网络设备层进行数据传输7、网卡驱动层进行数据传输8、数据传输的整个流程 1、write源码剖析 系统调用原型 ssize_t write(int fildes, const void *buf, si…

windows@浏览器主页被篡改劫持@360篡改主页@广告和弹窗设置@极速版

文章目录 360篡改浏览器主页方法1锁定浏览器主页 方法2注册表修改 360广告和弹窗360极速版 小结 360篡改浏览器主页 如果您使用360,且不想卸载它,那么当你启动360后,它可能会篡改你的浏览器(比如edge)的主页start page为360早期可能是通过修改快捷方式的target等属性,但是现在…

淘宝商品详情接口:解锁淘宝海量商品信息的秘密武器!

淘宝商品详情接口技术详解 淘宝作为中国最大的电子商务平台之一&#xff0c;其开放平台提供了丰富的API接口供开发者使用&#xff0c;以便第三方应用能够与淘宝平台无缝对接&#xff0c;实现数据交互和业务逻辑。其中&#xff0c;商品详情接口是众多API中非常重要的一项&#…

【LeetCode热题100】102. 二叉树的层序遍历(二叉树)

一.题目要求 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 二.题目难度 中等 三.输入样例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1…

算法笔记~—位运算

目录 常见位运算&#xff1a; 1、基础位运算 2、对于一个数n。确定、修改这个数n二进制x位。 3、提取&#xff08;确定&#xff09;一个数n最右侧的1&#xff08;bit&#xff09;与干掉最右侧的1&#xff08;bit&#xff09; 4、异或运算律 5、位运算的优先级&#xff1a…

网上国网App启动鸿蒙原生应用开发,鸿蒙开发前景怎么样?

从华为宣布全面启动鸿蒙生态原生应用一来&#xff0c;各种各样的新闻就没有停过&#xff0c;如&#xff1a;阿里、京东、小红书……等大厂的加入&#xff0c;而这次他们又与一个国企大厂进行合作&#xff1a; 作为特大型国有重点骨干企业&#xff0c;国家电网承担着保障安全、经…

GAMES Webinar 288-VR/AR专题-陆峰-混合现实中的多模态自然人机交互

感知交互增强智能 研究室虚拟现实技术与系统国家重点实验室&#xff0c;北京航空航天大学计算医学研究所&#xff0c;大数据精准医疗北京市高精尖创新中心 Perception & Hybrid Interaction (PHI) for Augmented & Affective Intelligence (A2I) We are working on v…

voxelize_cuda安装教程 python+windows环境

import voxelize_cuda报错 安装步骤&#xff1a; 克隆voxelize项目 官网&#xff1a;https://github.com/YuliangXiu/neural_voxelization_layer.git git clone https://github.com/YuliangXiu/neural_voxelization_layer.git下载一些必备的解析c文件的依赖 官网&#xff1a…

ES6 基础

文章目录 1. 初识 ES62. let 声明变量3. const 声明常量4. 解构赋值 1. 初识 ES6 ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得」JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为…

蓝牙HFP协议推荐的语音丢包补偿算法浮点实现的定点化

最近在做蓝牙的宽带语音通话。相对于蓝牙窄带语音&#xff0c;主要变化是把采样率从8k变到16k&#xff0c;以及编解码器从CVSD变成mSBC&#xff08;modified SBC&#xff0c;改进的SBC&#xff09;等。蓝牙语音通话相关的HFP&#xff08;Hand Free Profile&#xff09;强烈建议…

【线段树】第十三届蓝桥杯省赛C++ A组 Java C组 Python A组/B组《最长不下降子序列》(C++)

【题目描述】 给定一个长度为 N 的整数序列&#xff1a;,,⋅⋅⋅,。 现在你有一次机会&#xff0c;将其中连续的 K 个数修改成任意一个相同值。 请你计算如何修改可以使修改后的数列的最长不下降子序列最长&#xff0c;请输出这个最长的长度。 最长不下降子序列是指序列中的…

报道 | 2024年4月-2024年6月国际运筹优化会议汇总

封面图来源&#xff1a; https://www.pexels.com/zh-cn/photo/1181406/ 2023年2月-2024年6月召开会议汇总&#xff1a; The 24th European Conference on Evolutionary Computation in Combinatorial Optimisation (EvoCOP) Location: Aberystwyth, Wales, UK Important Date…