顺序表链表OJ题(3)——【数据结构】

W...Y的主页 😊

代码仓库分享 💕


前言:

 今天是链表顺序表OJ练习题最后一次分享,每一次的分享题目的难度也再有所提高,但是我相信大家都是非常机智的,希望看到博主文章能学到东西的可以一键三连关注一下博主。

话不多说,我们来看今天的OJ习题.。

【leetcode 142.环形链表II】

OJ链接

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

题目函数接口:

head:目标链表


分析:在上一篇博客中,我们讲述了如何寻找相遇点,创建两个指针slow与fast,fast的速度为slow的两倍,最终会在环中追及到。

下面讲述的方法与昨天的有关联: 

slow进入环后只会走不到一圈就会被fast追上,如果L足够长,环足够小fast会在环中走n圈(n>=1)。

我们分析完,题目就会迎刃而解。我们只需要先找到相遇点,然后一个指针从起点走,一个指针从相遇点走,它们相遇后的地址就是我们要的答案!!!

代码演示:

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *fast = head;struct ListNode *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow ){struct ListNode *cur = head;while(cur != slow){cur = cur->next;slow = slow->next;}return slow;}}return NULL;
}

 再给大家提供一种思路!!!

思路二:我们可以先找到相遇点,然后将环从相遇点截断,这个链表就变成了相交链表,然后找到相交链表的相交点即可。

这个想法很简便也很大胆,不知道相交链表已经做题方法的可以在顺序表链表OJ题(2)->【数据结构】中找到相交链表的介绍以及相关题型。

 

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {int lena = 1;int lenb = 1;struct ListNode *cura = headA;struct ListNode *curb = headB;while(cura->next){cura = cura->next;lena++;}while(curb->next){curb = curb->next;lenb++;}if(cura != curb){return NULL;}int gap = abs(lena-lenb);struct ListNode *llist = headA;struct ListNode *slist = headB;if(lena > lenb){;}else{llist = headB;slist = headA;}while(gap--){llist = llist->next;}while(llist != slist){llist = llist->next;slist = slist->next;}return llist;
}
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *fast = head;struct ListNode *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow){struct ListNode *meet = slow;struct ListNode *newhead = meet->next;meet->next = NULL;return getIntersectionNode(newhead, head);}} return NULL;
}

 【leetcode 138.复制带随机指针的链表】

OJ链接

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

题目函数接口:

head:目标链表


 这道题比较复杂,拷贝一般链表非常简单,但是这个链表比较特殊,在结构体中加入了随机指针,如果我们先将无random指针链表拷贝一份,再去寻找random指针在链表中指向的位置,会非常麻烦,我们必须不停遍历链表,时间复杂度就非常高O(n^2)。而且代码也会非常的复杂,不建议使用暴力解法。

现在唯一难点就是如何找到新链表中random对应的位置,因为创建新链表与目标链表的地址是没有任何关联的。

但是接下来的方法相对于暴力解法会非常轻松,这个想法也是非常新颖的!!

思路:

我们在原链表中每个结构体的后面插入新的结构体,将对应的内容拷贝到插入的新结构体中,就是这样:

这样我们就可以很方便的寻找random,创建一个指针copy,就比如上图中的13节点,我们需要拷贝13中的random到后面连接的新结构体中,只需要找到旧结构体中random指向的内容,让旧结构体的next的next->random等于copy指向的random即可。 最后一步只需要将完全拷贝好的新结构体拿下来尾插,组成一个新链表即可完成!!!

理论形成,时间开始:

struct Node* copyRandomList(struct Node* head) {struct Node*cur = head;while(cur){struct Node*next = cur->next;struct Node*copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;cur->next = copy;copy->next = next;cur = next;}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;}cur = head;struct Node*copyhead = NULL;struct Node*copytail = NULL;while(cur){struct Node* copy = cur->next;struct Node* next = copy->next;if(copytail == NULL){copyhead = copytail = copy;}else{copytail->next = copy;copytail = copytail->next;}cur->next = next;cur = next;}return copyhead;
}

 新节点插入老节点中、copy指针的寻找新链表……都需要我们画图更好的理解。

这两道题都是想法比较前卫,一般方法比较困难的题,虽然用c语言比较麻烦,但是等到后面我们掌握了map以及哈希结构就会非常简单。

以上就是本次OJ题目的全部内容,希望大家看完有收获,一键三连支持一下博主吧!!!😘😘 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言之数组题

目录 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 5.扫雷 6.概念辨析tips 我又来了,今天是数组题,本人还在补军训真的热!🆗 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 …

首席执行官Adam Selipsky解读“亚马逊云科技的技术产品差异化”

迄今为止,亚马逊云科技已经参与了21世纪几乎所有的大型计算变革,亚马逊云科技是一个很传奇的故事,它始于大约20年前的一项实验,当时亚马逊试图出售其过剩的服务器。人们确实对此表示怀疑。为什么在线书店试图销售云服务&#xff1…

RBAC实现授权

RBAC分为两种方式: 基于角色的访问控制(Role-Based Access Control) 基于资源的访问控制(Resource-Based Access Control) 角色的访问控制(Role-Based Access Control)是按角色进行授权&…

浅谈AI浪潮下的视频大数据发展趋势与应用

视频大数据的发展趋势是多样化和个性化的。随着科技的不断进步,人们对于视频内容的需求也在不断变化。从传统的电视节目到现在的短视频、直播、VR等多种形式,视频内容已经不再是单一的娱乐方式,更是涉及到教育、医疗、商业等各个领域。 为了…

JVM 内存大对象监控和优化实践

作者:vivo 互联网服务器团队 - Liu Zhen、Ye Wenhao 服务器内存问题是影响应用程序性能和稳定性的重要因素之一,需要及时排查和优化。本文介绍了某核心服务内存问题排查与解决过程。首先在JVM与大对象优化上进行了有效的实践,其次在故障转移与…

Unity——音乐、音效

在游戏运行的过程中,音效的播放时机与游戏当前内容密切相关,而且随着场景的变化、剧情的推进,背景音乐也需要适时切换,所以恰当地控制音乐和音效的播放非常重要。音乐和音效的播放、停止、切换和音量变化等,都需要由脚…

AS报错:CreateProcess error=206,文件名或扩展名太长

背景:今天编译公司的项目,第一次编译Ok,修改代码之后,第二次编译报错,报错信息:CreateProcess error206,文件名或扩展名太长。 同时删除build文件夹时报错:另一个程序正在使用此文件…

【C++】C/C++内存管理-new、delete

文章目录 一、C/C内存分布二、C/C中动态内存管理方式2.1 C语言中动态内存管理方式2.2 C内存管理方式 三、operator new和operator delete函数3.1 operator new和operator delete函数3.2 operator new与operator delete的类专属重载(了解) 四、new和delet…

「Redis」1. 数据类型的底层实现

前言:在这篇博文中,我们将简单总结在面试中怎么回答Redis数据类型的底层实现。 因为面试时间就那么点,言简意赅的描述自己会的知识显得尤为重要‼️ 文章目录 0.1. String 的底层实现原理0.2. 列表的底层实现原理0.3. 字典的底层实现原理0.4.…

【 ARMv9 Cluster BUS QoS 配置】

文章目录 ARM Cluster QoS ARM Cluster QoS QoS(Quality of Service,服务质量)在 ARM 架构中,主要指的是一种机制,它可以控制和管理系统资源(如内存、总线带宽等)的使用,以满足各种…

Leetcode刷题:395. 至少有 K 个重复字符的最长子串、823. 带因子的二叉树

Leetcode刷题:395. 至少有 K 个重复字符的最长子串、823. 带因子的二叉树 1. 395. 至少有 K 个重复字符的最长子串算法思路参考代码和运行结果 2. 823. 带因子的二叉树算法思路参考代码和运行结果 1. 395. 至少有 K 个重复字符的最长子串 题目难度:中等 标签&#…

Mybatis查询数据

上一篇我们介绍了在pom文件中引入mybatis依赖,配置了mybatis配置文件,通过读取配置文件创建了会话工厂,使用会话工厂创建会话获取连接对象读取到了数据库的基本信息。 如果您需要对上面的内容进行了解,可以参考Mybatis引入与使用…

【业务功能篇87】微服务-springcloud-本地缓存-redis-分布式缓存-缓存穿透-雪崩-击穿

一、缓存 1. 什么是缓存 缓存的作用是减低对数据源的访问频率。从而提高我们系统的性能。 缓存的流程图 2.缓存的分类 2.1 本地缓存 其实就是把缓存数据存储在内存中(Map <String,Object>).在单体架构中肯定没有问题。 单体架构下的缓存处理 2.2 分布式缓存 在分布式环…

无涯教程-Python机器学习 - Stochastic Gradient Boosting函数

它也称为梯度提升机。在下面的Python食谱中,我们将通过使用pima Indians糖尿病数据集上的 sklearn 的 GradientBoostingClassifier 类来创建随机梯度Boostingensemble模型进行分类。 首先,导入所需的软件包,如下所示: from pandas import read_csv from sklearn.model_select…

万户协同办公平台 ezoffice存在未授权访问漏洞 附POC

文章目录 万户协同办公平台 ezoffice存在未授权访问漏洞 附POC1. 万户协同办公平台 ezoffice简介2.漏洞描述3.影响版本4.fofa查询语句5.漏洞复现6.POC&EXP7.整改意见8.往期回顾 万户协同办公平台 ezoffice存在未授权访问漏洞 附POC 免责声明&#xff1a;请勿利用文章内的相…

第9章:聚类

聚类任务 性能度量 距离度量 非度量距离 原型聚类 有很好的统计学上的意义&#xff0c;但是只能找到椭球形的聚类。 密度聚类 层次聚类

信号和槽的相关操作

目录 信号和槽 connect()函数 自定义信号槽 例子 自定义信号槽需要注意的事项 信号槽的更多用法 Lambda表达式 ① 函数对象参数 ② 操作符重载函数参数 ③ 可修改标示符 ④ 错误抛出标示符 ⑤ 函数返回值 ⑥ 是函数体 所谓信号槽&#xff0c;实际就是观察者模式。当…

Mac Flutter web环境搭建

获取 Flutter SDK 下载以下安装包来获取最新的 stable Flutter SDK将文件解压到目标路径, 比如: cd ~/development $ unzip ~/Downloads/flutter_macos_3.13.0-stable.zip 配置 flutter 的 PATH 环境变量&#xff1a; export PATH"$PATH:pwd/flutter/bin" // 这个命…

RSA私钥解密操作

RSA私钥解密操作 一、背景二、操作三、常见问题3.1 invalid key format3.2 解密的数据太长3.3 Decryption error 一、背景 项目数据库中存放的敏感字段已使用rsa加密的方式&#xff0c;将内容加密成密文存放, 现在需要在使用的时候&#xff0c;使用私钥进行解密。 二、操作 …

cublas_v2.h没有那个文件和目录,解决

我的是orin&#xff0c;使用的cuda11.4&#xff0c;后来发现通过sudo jetson_release看到的CUDA是没有安装的。 定位到问题是&#xff1a; 使用ls /usr/local/ -lha查看软连接&#xff0c;如下&#xff1a; 能够发现cuda这个软连接是有问题的&#xff0c;他链接的是cuda10.2 …