【基础算法】单链表的OJ练习(6) # 复制带随机指针的链表 #
创始人
2025-05-29 10:59:21
0

文章目录

  • 🍇前言
  • 🍎复制带随机指针的链表
  • 🍑写在最后

🍇前言

  • 本章的链表OJ练习,是最后的也是最难的。对于本题,我们不仅要学会解题的思路,还要能够通过这个思路正确的写出代码,也就是思路转化为代码的过程,这应该就是最难的地方了吧。

  • 对于OJ练习(5): -> 传送门 <-,环形链表的做法的证明一定要理解透彻,因为面试很可能问到噢。


🍎复制带随机指针的链表

  • 题目链接:-> 传送门 <-

  • 题目描述:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。例如:如果原链表中有 XY 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 xy ,同样有 x.random --> y返回复制链表的头节点。

  • 也就是复制一个链表。

例如复制下面这个链表:(复制后返回复制后的链表的头节点)

在这里插入图片描述

解题思路:

  • 我相信,看到这个题,第一感觉就是暴力把他给复制了。但暴力终会达到O(N^2),虽然可以过,但如果面试的时候遇到这个问题,面试官可能就会问:如何将时间复杂度降到O(N)呢?

  • 所以这里使用一种O(N)的方法来解这道题。

  • 首先,我们在原链表上的每一个节点后面插入一个与自己有相同值的节点(称为copy节点),然后进行连接,如下:

在这里插入图片描述

  • 然后进行的操作是最关键的:再遍历一遍连接了copy节点后的链表,将每一个copy节点的random指向它前一个节点(就是被复制的那个节点,因此这里操作的时候,需要一个指针指向copy节点的前一个节点)的randomnext节点,如果copy的前一个节点的random指向NULL,那直接将copy节点的random指向NULL,直到遍历结束,可以得到下面这个链表:

在这里插入图片描述

  • 细心观察不难发现,上面的所有copy节点组成的链表实际上就与原链表相同了。

  • 因此最后的操作,就是将每一个copy节点取下来尾插到新的链表上,最后返回这个新链表的头即可。当然啦,这里还需要将原链表复原。

  • 根据上面的思路,会发现,如何将这些过程转换成代码是个难点。这里没得巧,就是多练,多写,正如:无他,唯手熟尔。

下面是代码实现(注意:一边写代码或者看代码,一边要体会整个思路的过程)

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while (cur){// 创建copy节点struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;// 存放当前节点的下一个节点的地址,便于连接和继续遍历链表struct Node* next = cur->next;// 连接cur->next = copy;copy->next = next;cur = next;}cur = head;while (cur){// 同样三个指针遍历struct Node* copy = cur->next;struct Node* next = copy->next;// 放置copy的random指针if (cur->random == NULL) copy->random = NULL;else copy->random = cur->random->next;cur = next;}// 新链表的头和连接新链表的指针struct Node* copyHead = NULL, *copyTail = NULL;cur = head;while (cur){// 同样需要三个指针来遍历struct Node* copy = cur->next;struct Node* next = copy->next;// 如果copyHead为NULL,先同时指向头节点if (copyHead == NULL) {copyHead = copyTail = copy;}else {copyTail->next = copy;copyTail = copyTail->next;}// 复原原链表cur->next = next;// 找下一个cur = next;}return copyHead;
}

🍑写在最后

对于单链表的题目练习,最重要的是思路,我们在数据结构阶段要养成画图的习惯,因为它能帮助我们更好的理解。单链表的OJ练习在此就结束了,大家要好好练习噢~

感谢阅读本小白的博客,错误的地方请严厉指出噢~

相关内容

热门资讯

打开的时光之书诗歌 打开的时光之书诗歌  (一)  一梦花开便让时光在回味中悠然,清霜微薰枫叶便在你的眸里羞红。  庭院...
经典的诗歌 经典的诗歌  在我们平凡的日常里,大家都经常接触到诗歌吧,诗歌在形式上,不是以句子为单位,而是以行为...
适合女生朗诵的诗歌 适合女生朗诵的诗歌(精选20篇)  在日常学习、工作和生活中,大家都知道一些经典的诗歌吧,诗歌是按照...
现代诗歌的格式 现代诗歌的格式  在日复一日的学习、工作或生活中,大家一定没少看到经典的诗歌吧,诗歌具有语言高度凝练...
Java中的集合 1 Java的集合 1 首先要知道集合是什么,基于现代汉语词典给定的定义: ...
ChatGPT-4.0 : 未... 文章目录前言ChatGPT 3.5 介绍ChatGPT 4.0 介绍ChatGPT -4出逃计划&#...
好听又励志的英文歌曲 好听又励志的英文歌曲  一、听唱英文歌曲的好处  听唱英文歌曲是一个轻松有效、被大量推荐的英文学习方...
经典的现代诗歌(精选)5篇 在学习、工作或生活中,大家都看到过许多经典的诗歌吧,诗歌具有精炼、集中,节奏鲜明,富有韵律的特点。还...
爱国的诗歌朗诵稿 爱国的诗歌朗诵稿7篇  在日复一日的学习、工作或生活中,许多人对一些广为流传的诗歌都不陌生吧,诗歌在...
汪国真经典现代诗歌《走向远方... 汪国真经典现代诗歌《走向远方》  《走向远方》这是一首寓意深刻,哲理深透的诗歌。给我们的启迪是深远的...
21根火柴游戏【C语言实现】 题目 21根火柴游戏。现有21根火柴,两人轮流取,每人每次可以取1至4根...
debian部署docker(... 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮...
代码随想录之回溯(力扣题号) 77 组合 改了非常非常非常久!!不知道为什么用set去重就是没成功。...
适合婚礼的诗词 适合婚礼的诗词  适合婚礼的诗词有哪些?诗词是指以古体诗、近体诗和格律词为代表的中国古代传统诗歌。亦...
青春诗歌欣赏 青春诗歌欣赏(通用10首)  无论是身处学校还是步入社会,大家都知道一些经典的诗歌吧,诗歌富于音乐美...
2021年庆祝元旦的优美诗歌 令人难忘的2020年既将过去,充满希望的2021年正向我们走来,2021年第一天元旦来了,那庆祝元旦...
关于重阳节的诗歌6篇 在日复一日的学习、工作或生活中,大家都收藏过令自己印象深刻的诗歌吧,诗歌具有语言高度凝练、篇幅短小精...
人脸识别经典网络-MTCNN(... 人脸检测-mtcnn 文章目录人脸检测-mtcnn1. 人脸检测1.1 人脸检测概述1.2 人脸检测...
强化学习笔记-04 动态规划D... 本文是博主对《Reinforcement Learning- An introduction》的阅读...
pikachu——xss 反射性(get)都提示get了,肯定跟url栏有关拿到题目...