【链表经典面试题】LeetCode138.复制带随机指针的链表(链表深拷贝)

📇文章目录

  • 🚀题目描述
  • 🚀思路1:
  • 🚀思路2:
  • 🚀完整代码

🚀题目描述

在这里插入图片描述
在这里插入图片描述

解读: 题目意思就是 给你一个链表 这个链表中除了有next指针之外 还有一个指向这个链表的随机位置的一个指针,让你复制这一个链表
而你复制之后的这个链表中的每一个节点的随机指针,也应该像原链表一样指向对应的节点

这里容易有一个误区,就是把拷贝之后的节点的随机指针random 置成原链表的random,这是不对的,因为他的意思是相当于让你把链表的结构也复制过来
比如说
原链表是7->13->11>10->1 ,其中13的random指向的是原链表中的7
那么你拷贝之后的链表也是 7->13->11->10->1 并且13指向拷贝之后的链表中的7

那么具体怎么做呢?
主要难搞的就是这个random 

🚀思路1:

7->13->11->10->1这个链表为例
复制之后我的13节点的random应该指向7 那么我遍历一遍去找值为7的节点不就可以了吗?
但是我们要想一想
如果这个链表是 7->7->13->11->10>1呢?
有两个节点的值都是7 ,那么返回哪一个呢? 是不是就不行了!
而且在效率方面最坏的情况,每一个节点都需要遍历一遍
时间复杂度是O(N^2)
所以这是一种错误思路!(怕就怕他有不止一个相同的值)

🚀思路2:

(想不到就没法做!!),技巧性很强,所以先看步骤

  1. 每一个拷贝的节点都直接链接在原节点的后面,形成一个大链表(考察链表节点的插入)在这里插入图片描述

  2. 然后通过原节点的random去找拷贝节点的random
    复制节点的random 就等于 原节点的randomnext(考察逻辑)
    如图分析在这里插入图片描述

    分析:拷贝链表中的random肯定和原链表中的random是有关系的,那么关系是什么呢?
    拷贝链表中的random一定指向了拷贝链表中的某一个节点
    这个节点怎么找呢?
    这就需要借助原链表
    因为我们把原链表和拷贝链表已经连接起来了,并且每一个拷贝节点是原链表的相同节点的next
    我们还是拿13这个节点为例,看上图
    原链表13的random指向的位置 的下一个就是与原链表13的random指向的节点的拷贝(注意理解这句话!!)
    之所以这么做是因为:拷贝链表的random要指向自己所在的链表的节点!
    所以 拷贝节点的random就是 原节点的random指向的next
    如果currandom为空,那么拷贝链表的random也为空

3.合并之后的链表拆分下来(考察链表的删除和尾插)
如图:在这里插入图片描述
也就是重新遍历一遍合并后的大链表
cur指向原链表,每一次循环 都定义一个copy节点等于curnext
把copy节点尾插到新的头 并把原链表中的相邻节点连接起来(相当于删除pos位置然后链接前后节点)

🚀完整代码

/**
 * 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)
    {
        //每一次都malloc一个新节点出来,把新节点和原链表连接起来
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        struct Node* next=cur->next;
        //copy的值 是cur的值
        copy->val=cur->val;
        //然后链接 cur copy next
        cur->next=copy;
        copy->next=next;
        //然后让cur向后走
        cur=next;

    }


    //2. 然后拷贝random指针
    
    cur=head;//让cur重新指向head
    while(cur)
    {
        //因为已经链接上了原链表
        // 所以每一次进来可以利用cur找到copy
        struct Node* copy=cur->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;;
        }
        else
        {
            copy->random=cur->random->next;
        }
        //然后更新cur
        cur=copy->next;
    }

    //3. 把原链表和拷贝链表分离开
    cur=head;
    struct Node* copyNhead=NULL,*copyTail=NULL;
    while(cur)
    {
        //每一次找到我的拷贝链表
        struct Node*copy=cur->next;
        // 拷贝链表的下一个(用于恢复原链表(链接原链表的两个节点))
        struct Node*next=copy->next;
        //如果新链表尾为空 那么就头插
        if(copyTail==NULL)
        {
            copyTail=copyNhead=copy;
        }
        else
        {
            // 如果拆出来的拷贝链表不为空 
            // 那么 tail的next赋值为copy
            // 然后 更新尾
            copyTail->next=copy;
            copyTail=copy;

        }
        // 然后cur向后走
        cur->next=next;//这是恢复原链表
        cur=next;
    }
    return copyNhead;

}

在这里插入图片描述
     感谢阅读哦 给个赞把~~😛

在这里插入图片描述

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

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

相关文章

简易人工智能入门

一、监督or非监督 监督学习(Supervised Learning):训练集有标记信息(Y),学习方式有分类和回归 无监督学习(Unsupervised Learning):训练集没有标记信息,学习…

事件驱动架构详解:触发与响应构建高效系统

目录 前言1. 事件驱动架构概述1.1 什么是事件1.2 事件驱动架构的核心概念 2. 事件驱动架构的实现2.1 基于消息队列的实现2.2 基于发布-订阅模式的实现2.3 基于流处理的实现 3. 事件驱动架构的优势3.1 松耦合性3.2 可扩展性3.3 异步处理3.4 灵活性 4. 事件驱动架构的应用场景4.1…

管道液位传感器在扫地机器人的应用

管道液位传感器在扫地机器人中的应用正日益受到重视。随着人们生活压力的增加,扫地机器人成为了解决家务烦恼的得力助手,而其中一个重要功能就是缺水提醒。实现这一功能的关键便是管道液位传感器。 管道液位传感器能够及时监测水箱中水的水位&#xff0…

工商业光伏项目怎么做?

随着全球对可再生能源的关注度不断提高,工商业光伏项目已成为企业实现绿色转型、降低能耗成本的重要途径。本文将详细介绍工商业光伏项目的开发流程,以及项目实施过程中需要注意的关键点。 一、项目前期准备 在启动工商业光伏项目之前,首先要…

buuctf----firmware

- -一定不能再ubutu22进行,我是在18(血泪教训) binwalk安装 buuctf firmware(binwalk和firmware-mod-kit的使用)_buu firmware-CSDN博客 参考博客 指令 sudo apt-get update sudo apt-get install python3-dev python3-setuptools python3-pip zlib1g-dev libmagic-dev pi…

oracle中执行select ... for update需要什么权限?

oracle中执行select … for update需要什么权限? 问题 在oracle中,一个用户执行select … for update需要什么权限? 分析测试 用户1: test_0614 用户2:test 目标表:test.t_0614 执行语句:se…

MySQL—索引—基础语法

目录 一、创建、查看以及删除索引的语法 (1)创建索引 1、1会用到一个关键字:CREATE。 1、2增加索引还可以用到另外一个关键字——ALTER TABLE 表名 ADD INDEX ... 。 2、解释。 (2)查看索引 1、查看索引需要用到…

Vue3模拟国足18强赛抽签

Vue3国足18强赛抽签 国足遇到这个对阵&#xff0c;能顺利出现吗&#xff1f; 1、系统演示 Vue3模拟国足18强赛抽签 2、关键代码 开始抽签 <script setup> import FenDang from "/components/chouqian/FenDang.vue"; import {ref} from "vue";le…

我又挖到宝了!小米、352、希喂宠物空气净化器除毛能力PK

养宠家庭常常因为猫咪们掉毛的问题烦恼。无论是短毛猫还是长毛猫&#xff0c;它们的毛发总是无处不在&#xff0c;从沙发到地毯&#xff0c;从床铺到衣物&#xff0c;甚至飘散在空气中。其中最难清理的就是飘浮在空气中的浮毛&#xff0c;最让人担心的是&#xff0c;空气中的浮…

TikTok 推出专属AI 内容工具

TikTok最近推出了一款极具实用性的新工具包——TikTok Symphony。它融合了生成式人工智能技术&#xff0c;让内容创作变得更加迅速和便捷。 无论是营销人员还是创作者&#xff0c;都能在TikTok上轻松制作出高质量的内容。Symphony将人类的创造力与AI的高效性完美融合&#xff0…

ARM32开发--存储器介绍

知不足而奋进 望远山而前行 目录 文章目录 前言 存储器分类 RAM ROM EEPROM Flash 总结 前言 在现代计算机系统中&#xff0c;存储器扮演着至关重要的角色&#xff0c;不仅影响着数据的存取速度和稳定性&#xff0c;还直接关系到计算机系统的性能和应用场景的选择。存…

【vue3】for循环多选框勾选必填校验

业务场景&#xff1a; 多选项必选一个&#xff0c;选了的输入框必填 <el-row :gutter"20"><el-col :span"12"><el-form-item label"捆绑终端硬件标识" prop"terminalCodeList"><el-checkbox-groupv-model"…

人工智能--搭建人工神经网络

欢迎来到 Papicatch的博客 文章目录 &#x1f349;引言 &#x1f349;神经元与感知器 &#x1f348;神经元&#xff08;Neuron&#xff09; &#x1f348;感知器 &#x1f349;损失函数与梯度下降算法 &#x1f348;损失函数 &#x1f348;梯度下降算法 &#x1f349;…

1. 基础设计流程(以时钟分频器的设计为例)

1. 准备工作 1. 写有vcs编译命令的run_vcs.csh的shell脚本 2. 装有timescale&#xff0c;设计文件以及仿真文件的flish.f&#xff08;filelist文件&#xff0c;用于VCS直接读取&#xff09; vcs -R -full64 -fsdb -f flist.f -l test.log 2. 写代码&#xff08;重点了解代码…

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据-08

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据 1. Kafka Broker 工作流程1.1 Zookeeper 存储的 Kafka 信息1.2 Kafka Broker总体工作流程1.2.1 Controller介绍 1.3 Broker 重要参数 2. 节点服役与退役3. Kafka副本 1. Kafka Broker 工作流程 …

找不到d3dx9_43.dll无法继续执行代码的几种解决方法

在工作或生活使用电脑都会遇到丢失dll文件应用无法启动的情况&#xff0c;比如你安装完一款你最喜欢的游戏在启动的时候提示系统缺少d3dx9_39.dll、d3dx9_40.dll、d3dx9_41.dll、d3dx9_42.dll、d3dx9_43.dll、xinput1_3.dll 文件而无法正常游戏&#xff0c;或你在工作的时候安装…

每日练题(py,c,cpp).6_19,6_20

检验素数 from math import sqrt a int(input("请输入一个数&#xff1a;")) for i in range(2,int(sqrt(a))):if a%i 0:print("该数不是素数")breakelse: print("该数是素数")# # 1既不是素数也不是合数 # #可以用flag做标志位 # b int(…

思聪私生女能继位吗?王健林表态,家族不会亏待

黄一鸣坚称&#xff1a;这绝对是王思聪的骨肉&#xff01;常言道&#xff0c;常在河边走&#xff0c;哪能不湿鞋。换女友如换装的王思聪&#xff0c;这次终于跌入了陷阱&#xff01;他的网红女友们如繁星点点&#xff0c;但选择标准始终如一——年轻、美丽。在金钱上&#xff0…

CARIS HIPS and SIPSv12 是专业的多波束水深数据和声呐图像处理软件

CARIS HIPS and SIPS是专业的多波束水深数据和声呐图像处理软件。CARIS HIPS and SIPS适用于海洋应用需求。其可靠性和可用性对多波束水深数据处理和声呐图像都是很重要的。CARIS HIPS用于处理多波束水深数据&#xff0c;CARIS SIPS用于处理侧扫声呐图像和多波束背向散射回波数…

Ascend C Add算子样例代码详解

核函数定义 核函数&#xff08;Kernel Function&#xff09;是Ascend C算子设备侧实现的入口。在核函数中&#xff0c;需要为在一个核上执行的代码规定要进行的数据访问和计算操作&#xff0c;当核函数被调用时&#xff0c;多个核都执行相同的核函数代码&#xff0c;具有相同的…