算法练习-环形链表(思路+流程图+代码)

难度参考

        难度:中等

        分类:链表

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回u。为了表示给定链表中的环,使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如果pos是-1,则在该链表中没有环。

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

        额外要求,不允许修改给定的链表

思路

        为了解决这个问题,首先需要了解 Floyd 的循环检测算法,又称为龟兔赛跑算法。该算法的核心思想是使用两个指针以不同的速度移动:一个快指针(通常称为 “hare”)和一个慢指针(通常称为 “tortoise” 或 “turtle”)。“hare” 以两倍的速度移动(两个节点一次),而 “tortoise” 以单倍速度移动(一个节点一次)。

        当两个指针都进入环时,快指针最终会追上慢指针。这是因为每次移动时,快指针都比慢指针多走一步。一旦快慢指针在环内相遇,我们就可以确定链表内确实存在一个环。

        接下来,找出环的入口点。当快慢指针第一次相遇,将快指针(或慢指针)重新设置到链表起点,这次两个指针都以相同速度前进,每次移动一个节点。当它们再次相遇的点,就是环的入口。

示例

        假设有以下链表:

    3 -> 2 -> 0 -> -4^          ||          v<----------
  1. 初始化两个指针 turtle(乌龟) 和 hare(兔子),它们都指向链表的头部节点 head(值为3的节点)。

  2. 循环开始,hare 以2步的速度移动,turtle 以1步的速度移动。在第一次迭代后,turtle 指向值为2的节点,hare 指向值为-4的节点。

  3. 继续迭代,hare 继续2步步进(移动到值为2的节点,因为链表有环),turtle 移动1步(现在指向值为0的节点)。

  4. 继续迭代,由于环的存在,hare 和 turtle 最终在值为0的节点相遇。这意味着链表有环。

  5. 在确认链表有环之后,将其中一个指针(这里是 turtle)移回到链表的头部,然后以相同的速度(每次移动一步)移动两个指针,当它们相遇时,即为环的起点。

  6. 在这个迭代中,turtle 从值为3的节点开始,而 hare 从值为0的节点开始。二者都向前移动一步。在第二步中,turtle 指向值为2的节点,hare 也指向值为2的节点,二者相遇,这就是环的入口节点。

梳理

        当检测到环存在时,根据 Floyd 的循环检测算法,我们可以确定环入口的位置。这是由以下数学逻辑得出的:

        让我们假设:

  • 链表头部到环入口的距离有 A 个节点
  • 环入口到乌龟和兔子的相遇点有 B 个节点
  • 相遇点回到环入口有 C 个节点

        因此,当乌龟和兔子在相遇点相遇时:

  • 乌龟走了 A + B 步
  • 兔子走了 A + B + k(C + B) 步,其中 k 是兔子在环里跑了完整的圈数

        因为兔子走得快(速度是乌龟的两倍),所以兔子走的步数是乌龟的两倍,得到等式:

  • 2(A + B) = A + B + k(C + B)
  • 通过简化等式我们得到 A = k(C + B) - B
  • 进一步简化得到 A = C + (k-1)(C + B)

        这个等式表示:从头部到环入口的距离 A 等于相遇点到环入口的距离 C 加上 (k-1) 个环的长度 (C + B)

        等式说明从链表头部到环入口的距离可以通过从相遇点继续走过 C,又或者走过 C + 整数倍的环长度(因为完整走过环的任何倍数,你都会再次回到相同的点)。这正是 Floyd 算法中的关键部分。

        因此,我们可以:

  1. 将一个指针重置到链表的起点。
  2. 让两个指针(一个从链表起点,另一个从相遇点)以相同的速度移动,每次一步。
  3. 两个指针相遇的地方就是环入口。

        所以,当这两个指针再次相遇时,该位置就是链表的环入口节点。在前面的例子中,图形化的解释就是,从头节点出发到达环入口(节点值2)需要走两步,从相遇点(节点值0)继续走回到环入口(节点值2)也正好是两步,因此两个指针会在环入口节点相遇。

代码

#include <iostream> // 引入输入输出流库
using namespace std; // 使用标准命名空间// 链表节点定义
struct ListNode {int val;          // 节点值ListNode* next;    // 下一个节点指针ListNode(int x) : val(x), next(nullptr) {} // 初始化构造函数
};// 检测链表是否有环,并返回环入口节点的函数
ListNode *getIntersectionNode(ListNode *head) {ListNode *turtle = head; // 初始化慢指针为头部ListNode *hare = head;   // 初始化快指针为头部// 使用快慢指针检测环bool isCycle = false; // 记录是否存在环while (hare != nullptr && hare->next != nullptr) {turtle = turtle->next;           // 慢指针前进一步hare = hare->next->next;         // 快指针前进两步if (turtle == hare) {            // 若快慢指针相遇isCycle = true;              // 确认有环break;                       // 跳出循环}}if (!isCycle) {return nullptr; // 无环返回 nullptr}// 寻找环的入口turtle = head; // 将慢指针重置到头部while (turtle != hare) { // 当快慢指针不相遇turtle = turtle->next; // 慢指针前进一步hare = hare->next;     // 快指针前进一步}return hare; // 返回环的入口节点
}// 主函数
int main() {// 创建链表并设置成环形ListNode *head = new ListNode(3);  // 头部节点值为3head->next = new ListNode(2);      // 第二个节点值为2head->next->next = new ListNode(0); // 第三个节点值为0head->next->next->next = new ListNode(-4); // 第四个节点值为-4// 设置环形链表指向位置 pos = 1,即节点值为2的节点head->next->next->next->next = head->next;// 检测环入口节点ListNode *entry = getIntersectionNode(head);// 如果存在环入口节点则输出,否则输出 nullptrif (entry != nullptr) {cout << "节点" << entry->val << endl; // 存在环,输出环入口节点的值} else {cout << "nullptr" << endl; // 无环的情况,输出 nullptr}// 已省略删除链表节点。return 0; // 程序结束
}

打卡

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

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

相关文章

用Jmeter进行接口测试

web接口测试工具&#xff1a; 手工测试的话可以用postman &#xff0c;自动化测试多是用到 Jmeter&#xff08;开源&#xff09;、soupUI&#xff08;开源&商业版&#xff09;。 下面将对前一篇Postman做接口测试中的接口用Jmeter来实现。 一、Jmeter 的使用步骤 打开Jme…

SpringCloud Gateway(4.1.0) 返回503:原因分析与解决方案

文章目录 一、环境版本二、原因分析三、解决方案 一、环境版本 Versionspring-cloud-dependencies2023.0.0spring-cloud-starter-gateway4.1.0Nacosv2.3.0 二、原因分析 在 Spring Cloud Gateway 的早期版本中&#xff0c;Ribbon 被用作默认的负载均衡器。随着Spring Cloud的…

修复wordpress安全漏洞

1. 问题描述&#xff1a; 用wordpress建了一个网站&#xff0c;但是学校反映说存在安全漏洞&#xff0c;通过接口https://xxx.xxx.edu.cn/?rest_route/wp/v2/users/可以访问到一些内容&#xff0c;希望可以关闭这个接口。 2. 解决办法 一共两步 &#xff08;1&#xff09;在fu…

系统架构20 - 统一建模语言UML(上)

统一建模语言 组成要素事物关系 在目前的软件开发方法中&#xff0c;面向对象的方法占据着主导地位。面向对象方法的主导地位也决定着软件开发过程模型化技术的发展&#xff0c;面向对象的建模技术方法也就成为主导的方法。 公认的面向对象建模语言出现于20世纪70年代中期。从1…

vulhub中Adminer ElasticSearch 和 ClickHouse 错误页面SSRF漏洞复现(CVE-2021-21311)

Adminer是一个PHP编写的开源数据库管理工具&#xff0c;支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其4.0.0到4.7.9版本之间&#xff0c;连接 ElasticSearch 和 ClickHouse 数据库时存在一处服务端请求伪造漏洞&#xff08…

学习ArtTs -- 初见ArkTs

作者&#xff1a;Uncle_Tom 原文链接&#xff1a;学习ArtTs -- 初见ArkTs-云社区-华为云 1. 前言 需要静态分析去检查一个语言&#xff0c;必须对这个语言有深刻的认识&#xff0c;才能有效的对这个语言进行有效的检查。 我常说:“作为一个程序分析员需要比一般的程序员考虑…

反演LAI(二)基于查找表的反演

反演LAI(二)基于查找表的反演 相关波段选取 首先我们使用gf-1数据有四个波段,使用其他高光谱会有几十个波段,但并不是所有波段都需要选用,lai对于不同波段的响应不同。根据上一节的敏感性分析结果,可以发现,400-500,600-700的两个波段对于LAI敏感性更大,因此选取这两…

【人工智能时代】AI赋能编程 | 自动化工具助力高效办公

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言泡泡AI工具卡片思维导图Markdown编辑器 其他工具文件免费处理工具结语 合集…

【C/C++ 11】贪吃蛇游戏

一、题目 贪吃蛇游戏机制是通过控制蛇上下左右移动并吃到食物得分。 蛇头碰到墙壁或者碰到蛇身就游戏结束。 食物随机生成&#xff0c;蛇吃到食物之后蛇身变长&#xff0c;蛇速加快。 二、算法 1. 初始化游戏地图并打印&#xff0c;地图的边缘是墙&#xff0c;地图的每个坐…

Python tkinter (14) —— 按键事件

本文主要介绍Python tkinter 几种按键事件及其示例。 目录 按键事件 响应所有按键事件 窗体绑定事件 响应特殊按键事件 指定按键事件 组合按键事件 总结 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— But…

Kafka相关内容复习

为什么要用消息队列 解耦 允许你独立的扩展或修改两边的处理过程&#xff0c;只要确保它们遵守同样的接口约束。 可恢复性 系统的一部分组件失效时&#xff0c;不会影响到整个系统。消息队列降低了进程间的耦合度&#xff0c;所以即使一个处理消息的进程挂掉&#xff0c;加入队…

Transformer 自然语言处理(三)

原文&#xff1a;Natural Language Processing with Transformers 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第八章&#xff1a;使 transformers 在生产中更高效 在之前的章节中&#xff0c;您已经看到了 transformers 如何被微调以在各种任务上产生出色的结果。…

AI 数字人从制作到变现

最近AI很火&#xff0c;无意中发现一个宝藏专栏《AI数字人从制作到变现》&#xff0c;原价599&#xff0c;现在推广阶段&#xff0c;只需要10元&#xff0c;专栏持续更新中&#xff0c;会有更多的知识后续分享。如有兴趣可以用微信扫描左侧海报二维码&#xff0c;下面我将介绍专…

『运维备忘录』之 Cron 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

计算机设计大赛 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…

ping 不支持代理,命令行测试外网网址请使用 curl 测试,如何测试?

如果你想通过命令行测试外网网址的可达性&#xff0c;并且因为 ping 命令不支持通过代理服务器进行操作&#xff0c;你可以使用 curl 命令来测试。curl 是一个强大的工具&#xff0c;可以用来传输数据&#xff0c;它支持多种协议&#xff0c;包括 HTTP、HTTPS 等&#xff0c;而…

6个国内可用的chat大模型

文心一言 - 一款适合中国人使用的AI智能助理&#xff0c;能够帮助用户进行对话、生成内容等工作&#xff0c;提高工作效率和创作水平 文心一言 文心一言 App 是一款适合中国人的 AI 智能助理&#xff0c;它的功能点主要包括&#xff1a; 工作生活助理&#xff1a;该应用通过简…

OJ刷题:《剑指offer》之单身狗1、2 !(巧用位操作符,超详细讲解!)

目录 1.单身狗1 1.1 题目描述 1.2排序寻找 1.3巧用位操作符 2.单身狗2 1.1 题目描述 1.2排序寻找 1.3巧用位操作符 不是每个人都能做自己想做的事&#xff0c;成为自己想成为的人。 克心守己&#xff0c;律己则安&#xff01; 创作不易&#xff0c;宝子们&#xff01;如…

智慧未来已至:人工智能与数字孪生共筑城市新纪元

随着科技的飞速发展&#xff0c;人工智能与数字孪生技术正逐步成为智慧城市建设的核心驱动力。 这两项技术的结合&#xff0c;不仅将彻底改变城市的传统面貌&#xff0c;更将引领我们走向一个更加高效、便捷、绿色的未来。 一、智慧城市的新内涵 智慧城市&#xff0c;是指在城…

移动Web——less

1、less-简介 less是一个CSS预处理器&#xff0c;Less文件后缀是.less。扩充了CSS语言&#xff0c;使CSS具备一定的逻辑性、计算能力注意&#xff1a;浏览器不识别Less代码&#xff0c;目前阶段&#xff0c;网页要引入对应的CSS文件VS code插件&#xff1a;Easy LESS&#xff…