[C/C++]数据结构 链表OJ题:随机链表的复制

news2024/11/23 20:14:06

题目描述:

        给你一个长度为 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]]

解题思路:

        这个题目描述这么长,其实就是说让我们完全复制一个和原链表相同的链表.这个题麻烦的地方是每个结点都有一个随机指针指向链表的随机一个位置.

思路一: (不推荐麻烦)

        遍历一遍原链表,先不管结点中random的指向问题,把所有malloc的结点的random指向NULL,复制出一条新链表,再解决random指向的问题.

        对于random的指向问题,我们可以遍历原链表,找每个结点的random指向的是链表中的第几个结点

例如:

        原链表第一个结点的random指向了原链表中的第五个结点,那我们就让我们创建的新链表中的第一个结点的random指向先链表中的第五个结点,以此类推,这样就可以解决新链表的random指向问题,但是这样处理每个结点的random都需要遍历一次原链表和新链表,时间复杂度达到了O(n^2),

下面这个思路可以把时间复杂度优化到O(n);

思路二:  (最优解)

        思路1是直接复制了一个新链表,而处理新链表的random并不能让其指向原链表的结点.只能指向自己创建的结点,这样就只能靠random指向的结点在原链表中的位置处理新结点的random指向.

所以我们可以在原链表每个结点后面插入一个相同的结点,这样处理结点的random问题就会简单很多.

如图所示:

        拷贝的结点都在原结点之后,这样原结点random所指结点的下一个结点便是拷贝结点的random应指向的结点

        处理好random问题后,只需要恢复原链表和分离拷贝链表就好了

   1 . 拷贝结点到原结点后面

    struct Node* cur=head;
    while(cur)
    {
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;

        copy->next=cur->next;
        cur->next=copy;
        
        cur=copy->next;
    }

   2. 处理random指针

    cur=head;
    while(cur)
    {
         struct Node* copy=cur->next;
         if(cur->random==NULL)
         {
             copy->random=NULL;
         }
         else
         {
             copy->random=cur->random->next;
         }

         cur=copy->next;
    }

  3. 分离拷贝链表和复原原链表

 struct Node* newhead=NULL,*tail=NULL;
     cur=head;
     while(cur)
     {
         struct Node* copy=cur->next;
         struct Node* next=copy->next;

         if(tail==NULL)
         {
             tail=newhead=copy;
         }
         else
         {
             tail->next=copy;
             tail=tail->next;
         }
         cur->next=next;

         cur=next;
     }

  题目参考代码:


struct Node* copyRandomList(struct Node* head) {
	//拷贝结点到原结点后面
    struct Node* cur=head;
    while(cur)
    {
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;

        copy->next=cur->next;
        cur->next=copy;
        
        cur=copy->next;
    }

    //处理random指针
    cur=head;
    while(cur)
    {
         struct Node* copy=cur->next;
         if(cur->random==NULL)
         {
             copy->random=NULL;
         }
         else
         {
             copy->random=cur->random->next;
         }

         cur=copy->next;
    }
    //分离拷贝链表和复原原链表
     struct Node* newhead=NULL,*tail=NULL;
     cur=head;
     while(cur)
     {
         struct Node* copy=cur->next;
         struct Node* next=copy->next;

         if(tail==NULL)
         {
             tail=newhead=copy;
         }
         else
         {
             tail->next=copy;
             tail=tail->next;
         }
         cur->next=next;

         cur=next;
     }

     return newhead;
}

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

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

相关文章

Python武器库开发-flask篇之URL重定向(二十三)

flask篇之URL重定向(二十三) 通过url_for()函数构造动态的URL: 我们在flask之中不仅仅是可以匹配静态的URL,还可以通过url_for()这个函数构造动态的URL from flask import Flask from flask import url_forapp Flask(__name__)app.route(/) def inde…

B031-网络编程 Socket Http TomCat

目录 计算机网络网络编程相关术语IP地址ip的概念InerAdress的了解与测试 端口URLTCP、UDP和7层架构TCPUDPTCP与UDP的区别和联系TCP的3次握手七层架构 Socket编程服务端代码客户端代码 http协议概念Http报文 Tomcat模拟 计算机网络 见文档 网络编程相关术语 见文档 IP地址 …

Python--快速入门四

Python--快速入门四 1.Python函数 1.在括号中放入函数的参数。 2.可以通过return在函数作用域外获取函数作用域内的值。(默认的return值为None) 代码展示:BMI计算函数 def calculate_BMI(fuc_height,fuc_weight):fuc_BMI fuc_weight/(fuc_height**2)return fuc…

转载:YOLOv8改进全新Inner-IoU损失函数:扩展到其他SIoU、CIoU等主流损失函数,带辅助边界框的损失

0、摘要 随着检测器的快速发展,边界框回归(BBR)损失函数不断进行更新和优化。然而,现有的 IoU 基于 BBR 仍然集中在通过添加新损失项来加速收敛,忽略了 IoU 损失项本身的局限性。尽管从理论上讲,IoU 损失可…

Linux-查询目录下包含的目录数或文件数

1. 前置 1)ls Linux最常用的命令之一,列出该目录下的包含内容。 -l:use a long listing format-以列表的形式展现 -R:list subdirectories recursively-递归列出子目录 2)| 管道符 将上一条命令的输出&#xff…

BUUCTF 被劫持的神秘礼物 1

BUUCTF:https://buuoj.cn/challenges 题目描述: 某天小明收到了一件很特别的礼物,有奇怪的后缀,奇怪的名字和格式。小明找到了知心姐姐度娘,度娘好像知道这是啥,但是度娘也不知道里面是啥。。。你帮帮小明&#xff1…

网络类型及数据链路层的协议

网络类型 --- 根据数据链路层使用的协议来进行划分的。 MA网络 --- 多点接入网络 BMA --- 广播型多点接入网络---以太网协议 NBMA --- 非广播型多点接入网络 以太网协议 --- 需要使用mac地址对不同的主机设备进行区分和标识 --- 以太网之所以需要使用mac地址进行数据寻址&…

PVE Win平台虚拟机下如何安装恢复自定义备份Win系统镜像ISO文件(已成功实现)

环境: Virtual Environment 7.3-3 Win s2019 UltraISO9.7 USM6.0 NTLite_v2.1.1.7917 问题描述: PVE Win平台虚拟机下如何安装恢复自定义备份Win系统镜像ISO文件 本次目标 主要是对虚拟机里面Win系统备份做成可安装ISO文件恢复至别的虚拟机或者实体机上 解决方案: …

.Net8 Blazor 尝鲜

全栈 Web UI 随着 .NET 8 的发布,Blazor 已成为全堆栈 Web UI 框架,可用于开发在组件或页面级别呈现内容的应用,其中包含: 用于生成静态 HTML 的静态服务器呈现。使用 Blazor Server 托管模型的交互式服务器呈现。使用 Blazor W…

『C++成长记』C++入门——内联函数

🔥博客主页:小王又困了 📚系列专栏:C 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、内联函数 📒1.1内联函数的概念 📒1.2内联函数的特征 …

在IDEA中的DeBug调试技巧

一、条件断点 循环中经常用到这个技巧,例如:遍历1个List的过程中,想让断点停在某个特定值。 参考上图,在断点的位置,右击断点旁边的红点,会出来1个界面,在Condition这里填写断点条件即可&#…

Swift--字符、字符串与集合类型

系列文章目录 第一章:量值与基本数据类型 第二章:字符、字符串与集合类型 文章目录 系列文章目录字符串组合 三种集合数组集合字典类型 Swift是一种弱化指针的语言,它提供了String类型和Character类型来描述字符串与字符 //构造一个字符串 …

OpenHarmony应用开发入门教程(一、开篇)

前言 华为正式宣布2024年发布的华为鸿蒙OS Next版将不再兼容安卓系统。这一重大改变,预示着华为鸿蒙OS即将进入一个全新的阶段。 都说科技无国界,这是骗人的鬼话。谷歌的安卓12.0系统早已发布,但是自从受到美影响,谷歌就拒绝再向…

VS Code如何使用服务器的Python开发环境

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

Linux常用命令——bzdiff命令

在线Linux命令查询工具 bzdiff 直接比较两个.bz2压缩包中文件的不同 补充说明 bzdiff命令用于直接比较两个“.bz2”压缩包中文件的不同,省去了解压缩后再调用diff命令的过程。 语法 bzdiff(参数)参数 文件1:指定要比较的第一个.bz2压缩包&#xf…

wpf devexpress显示总结

这个教程示范如何显示总结对于列分组和单个数据行。这个教程基于前一篇 GridControl 可以计算如下总结: 这个数据列(Count) 这个最大和最小值(Max和Min)。 总结和平均值(Sum和平均值) 自定义…

我们常说的网络资产,具体是如何定义的?

文章目录 什么叫网络资产?官方定义的网络资产网络资产数字化定义推荐阅读 什么叫网络资产? 通过百度查询搜索什么叫网络资产?大体上都将网络资产归类为计算机网络中的各类设备。 基本上会定义网络传输通信架构中用到的主机、网络设备、防火…

van-dialog弹窗异步关闭-校验表单

van-dialog弹窗异步关闭 有时候我们需要通过弹窗去处理表单数据,在原生微信小程序配合vant组件中有多种方式实现,其中UI美观度最高的就是通过van-dialog嵌套表单实现。 通常表单涉及到是否必填,在van-dialog的确认事件中直接return是无法阻止…

【差旅游记】启程-新疆哈密(2)

哈喽,大家好,我是雷工。 最近需要出差,11月02号第一次去新疆特意记录下去新疆的过程。 01 又过北京西站 本来订的是途径成都中转的路线,结果飞机改点,中转时间太短导致赶不上下班飞机,只好改道北京。 又到…

通信原理板块——利用香农公式对连续信道的信道容量计算

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 利用香农公式对连续信道的信道容量…