环形链表2--绝妙的运算

一、要求

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

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

不允许修改 链表。

二、思路

基本思路和上一个环形链表(如果有疑问可以移步上一篇博客查看)大部相同,但存在一个关键问题上的不同点。

使用快慢指针的方式来解决环形链表问题。

首先定义两个指向head的struct ListNode*类型的指针变量用来记录开始位置;

接下来判断链表是否为空链表以及链表的首项指向的地址是否为空;

确保上述条件后开始让phead1和phead2分别向前走一步和两步;

再他们向后走的过程中一旦遇到指向NULL的问题说明该链表不是环形链表;

不为NULL就继续向后走;

此时按照上述判断已经确定该链表为环形链表;

对链表的地址进行判断,当两链表指向的地址相同时说明该链表为环形链表。

关键结论:

使phead2和head同时向后一步一步的走,最终他们会在环形链表的入口处相遇!

我们在知道了这个结论以后开始对这个结论进行论证;

//        //             我们假设环状链表环的起点到头部的距离为L 
//        //             环的长度为C
//        //             phead1和phead2相交的位置到环状链表环的起点的位置为X
//        //             此时可以得到L = N*C-X(N为phead2多走的圈数)
//        //             L = (N-1) * C + C - X
//        //             也就是说phead2是从x开始走的,他们两个走的距离刚好越过了X即L = N * C                                   两者的相遇点就是环形链表的起点

三、画图理解 

ps:环形链表的论证已经在上一篇博客中详细解释,在这里不再进行过多赘述,谢谢理解。

四、代码实现

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode * phead1 = head;struct ListNode * phead2 = head;while(phead2&&phead2->next){phead1 = phead1->next;phead2 = phead2->next->next;if(phead1 == phead2){while(head!=phead2){head= head->next;phead2=phead2->next;}return head;}}return NULL;
}

五、小思考

如果走的距离不是1和2,他们是否还能相遇?

后面为什么直接使用head而不是创建一个临时指针用于替代它呢?

请将答案放在评论区吧!

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

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

相关文章

FPGA高端项目:解码索尼IMX327 MIPI相机+2路视频融合叠加,提供开发板+工程源码+技术支持

目录 1、前言2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX327 及其配置MIPI CSI RX图像 ISP 处理HLS多路视频融合叠加图像缓存HDMI输出工程…

Unity 使用 IL2CPP 发布项目

一、为什么用 IL2CPP Unity的IL2CPP(Intermediate Language to C)是一个编译技术,它将C#代码转换为C代码,然后再编译成平台相关的二进制代码。IL2CPP提供了几个优点,特别是在性能和跨平台部署方面。以下是IL2CPP的一些…

在OKR的管理中,管理者应该如何切实有效的追踪进展,确保其有效落地?

在OKR(Objectives and Key Results,目标与关键成果)的管理中,管理者对于进展的追踪是确保整个系统有效落地的重要环节。有效的追踪不仅能帮助团队保持对目标的清晰认知,还能及时发现问题,调整策略&#xff…

多线程学习-线程池

目录 1.线程池的作用 2.线程池的实现 3.自定义创建线程池 1.线程池的作用 当我们使用Thread的实现类来创建线程并调用start运行线程时,这个线程只会使用一次并且执行的任务是固定的,等run方法中的代码执行完之后这个线程就会变成垃圾等待被回收掉。如…

Vue2(十三):Vuex环境搭建、Vuex工作原理、几个配置项、多组件共享数据、Vuex模块化

一、Vuex 1.理解 1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。 2…

对抗样本攻击

对抗样本是指经过特殊设计或调整的输入数据,旨在欺骗人工智能模型,使其产生错误的预测或输出。对抗样本通常是通过对原始输入进行微小但精心计算的改变,使得模型产生意外的结果。这种模糊化的输入可能难以从人类角度甄别,但对机器…

顺序表的应用

文章目录 目录1. 基于动态顺序表实现通讯录项目2.顺序表经典算法2.1 [移除元素](https://leetcode.cn/problems/remove-element/description/)2.2 [合并两个有序数组](https://leetcode.cn/problems/merge-sorted-array/description/) 3. 顺序表的问题及思考 目录 基于动态顺序…

随机森林、AdaBoost 和 XGBoost 三者之间的主要区别

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 集成学习是一种强大的机器学习范式,它通过构建并结合多个学习器来提高预测性能。其中,随机森林、AdaBoost 和 XGBoost 是集成学习领域中著名且广泛应用的方法。尽管这些方法共享…

比selenium体验更好的ui自动化测试工具: cypress介绍

话说 Cypress is a next generation front end testing tool built for the modern web. And Cypress can test anything that runs in a browser.Cypress consists of a free, open source, locally installed Test Runner and a Dashboard Service for recording your tests.…

os.listdir()bug总结

今天测试出一个神奇的bug,算是教训吧,找了两天不知道问题在哪,最后才发现问题出现在这 原始文件夹显示 os.listdir()结果乱序 import os base_path "./file/"files os.listdir(base_path)print(files)问题原因 解决办法(排序)

蓝桥杯第十四届C++A组(未完)

【规律题】平方差 题目描述 给定 L, R,问 L ≤ x ≤ R 中有多少个数 x 满足存在整数 y,z 使得 。 输入格式 输入一行包含两个整数 L, R,用一个空格分隔。 输出格式 输出一行包含一个整数满足题目给定条件的 x 的数量。 样例输入 1 5 样例输出 …

文件怎么做成二维码图片?怎么用手机扫描二维码下载文件?

文件如何生成二维码图片?随着互联网的不断发展,用二维码来传递内容已经成为一种很常用的方式,其他人可以通过手机扫描生成二维码的方式来查看或者下载文件内容,有效提升文件传输的效率和速度。 现在制作活码类型的二维码可以在图…