当前位置: 首页 > java >正文

链表面试题10之随机链表的复制

好,这篇文章将是链表面试题的最后一题,后面就将进入队列和二叉树。

老规矩可以往前回顾一下我们的思考。

这里继续把题目链接贴一下:138. 随机链表的复制 - 力扣(LeetCode)

 

乍一看整个图我们摸不着一点头脑,但是没关系,我们先来看一下,题目所给出的例子中,这个链表有两个指针域, 那这非常像两个单链表的叠加,或者说,我们再来看一下双向链表,是否可以把这个链表比拟成双向链表去理解,来更好地让我们探索题意。

没学过双向链表也不要紧,下面是双向链表:

 也就是说,双向链表就是可以两头都进行增删查改的链表,一定程度上既可以向前遍历,又可以向后遍历,那么这道题目里面不就也可以看成这样吗,不过是前指针指向是随机的,我们不知道如何处理而已。

再回头看我们的题目,要求我们复制这个随机链表,那么对于这种遍历并输出的做法,我们一般马上就想到迭代,这应该是肌肉记忆了,因为仅用遍历是存储不了而导致输出不了内容的。

迭代法:时间复杂度O(n)

题目要求我们复制一个长度为 n 的链表,该链表除了每个节点有一个指针指向下一个节点外,还有一个额外的指针指向链表中的任意节点或者 null,如下图所示:

把原图的画直了我们就发现问题其实很简单,就是分治的思想 ,首先让我们去复制一个普通的单链表肯定没问题,难的就是复制一个带随机指针的链表

如何去复制一个带随机指针的链表?

首先我们可以忽略 random 指针,然后对原链表的每个节点进行复制,并追加到原节点的后面,而后复制 random 指针。最后我们把原链表和复制链表拆分出来,并将原链表复原。

图示过程如下:

1、在每个节点的后面加上它的复制,并将原链表和复制链表连在一起。

2.从前往后遍历每一个原链表节点,对于有 random 指针的节点 p,我们让它的

p->next->random = p->random->next,这样我们就完成了对原链表 random 指针的复刻。

3、最后我们把原链表和复制链表拆分出来,并将原链表复原。

 

这里先给大家贴一下代码,再讲一下为什么要这么做:

class Solution {
public:Node* copyRandomList(Node* head) {for(auto p = head; p; p = p->next->next)  //复制每个节点,并将原链表和复制链表连在一起。{auto q = new Node(p->val);q->next = p->next;p->next = q;}for(auto p = head; p; p = p->next->next)   //复制random指针{if(p->random)p->next->random = p->random->next;}//拆分两个链表,并复原原链表auto dummy = new Node(-1), cur = dummy; for(auto p = head; p; p = p->next){auto q = p->next;cur = cur->next = q;p->next = q->next;}return dummy->next;}
};

 为什么要想到这种方法呢?因为复制链表的时候我们无法复制原来链表的random的指向,我们只能复制单链表,那我们如果复制一个链表的话就得让新链表的指向也指向新链表的元素,两个链表之间基本上没有关联,这个时候就得别具一格,也就是说强行链接关系。

好了,这道题就讲到这里

如果你觉得对你有帮助,可以点赞关注加收藏,感谢您的阅读,我们下一篇文章再见。

一步步来,总会学会的,首先要懂思路,才能有东西写。

http://www.xdnf.cn/news/9121.html

相关文章:

  • Windows环境下Redis的安装使用与报错解决
  • DeepSpeed-Ulysses:支持极长序列 Transformer 模型训练的系统优化方法
  • 技术视界 | 打造“有脑有身”的机器人:ABC大脑架构深度解析(上)
  • Redisson使用分布锁的详解
  • LTC之管理线索:企业抢占市场先机的制胜法宝
  • 第7章 C控制语句:分支和跳转
  • AI赋能天气预测:微软 Aurora 模型
  • 工业视觉阈值技术圣经:VisionMaster六维算法解析+脑图攻防手册
  • Selenium 测试框架 - .NET
  • 有铜半孔的设计规范与材料创新
  • 苍穹外卖--Redis
  • JavaScrip 中 reduce 函数用法详解
  • (请关注)Oracle性能调优、优化总结调优参考直接应用,性能提升实用案例
  • 时代变了,我选择ApiFox替代Postman
  • einops.layers.torch.Rearrange作用
  • 计算机网络实验课(一)——配置+实验一:查看当前主机所有的网卡信息
  • 2.1 C++之条件语句
  • 5.26打卡
  • RK3588 buildroot 双网口bonding调试
  • MERIT:用于可靠且可解释的肝纤维化分期的多视图证据学习|文献速递-深度学习医疗AI最新文献
  • 【前端兼容】深入实战:vw/vh 视口单位的高效应用与避坑指南
  • Linux系统使用docker部署SpringBoot+vue项目详细【从零开始,亲测有效】
  • 机试 | vector/array Minimum Glutton C++
  • 微信语音类输入发送功能测试
  • 【更新至2023年】1985-2023年全国及各省就业人数数据(无缺失)
  • QT学习一
  • 战略管理数字化的全面解决方案 ---iDSTE:集成战略管理软件的开创者与引领者
  • 110 kV覆冰绝缘子电场分布特性有限元分析报告
  • Wave Terminal + Cpolar:SSH远程访问的跨平台实战+内网穿透配置全解析
  • BeanUtil和BeanUtils有什么区别