如何判断一个链表是否有环?

如何判断一个链表是否有环?

判断一个链表是否有环是一个经典的算法问题,它涉及到链表遍历和数据结构的基本概念。在链表中,每个节点通常包含两部分:一部分存储数据,另一部分存储指向下一个节点的指针。如果链表中存在某个节点,其下一个节点直接或间接地指回了之前的某个节点(包括它自身),则称该链表存在环。

为了判断链表是否有环,我们可以采用多种方法,其中两种最常见且有效的方法是:

  1. 使用快慢指针(龟兔赛跑算法)
  2. 使用哈希表(集合)

下面将详细解释这两种方法,并给出相应的实现代码。

一、使用快慢指针(龟兔赛跑算法)

这种方法的思想来源于一个经典的逻辑悖论——阿基里斯与乌龟赛跑。在这里,“快指针”(兔子)每次移动两步,而“慢指针”(乌龟)每次移动一步。如果链表中没有环,快指针最终会到达链表的末尾(即指向null)。如果链表中存在环,快指针最终会在某个时刻与慢指针相遇,因为它们会以相同的速度在环内移动。

算法步骤

  1. 初始化两个指针,slowfast,都指向链表的头节点。
  2. 进入循环,条件是fastfast.next都不为null(因为快指针每次移动两步,需要确保它不会越界)。
  3. 在每次循环中,slow指针移动一步(slow = slow.next),而fast指针移动两步(fast = fast.next.next)。
  4. 如果在某个时刻slowfast相遇,则链表中存在环,返回true
  5. 如果快指针到达链表的末尾(即fastfast.nextnull),则链表中不存在环,返回false

实现代码(Python):

class ListNode:
def __init__(self, value=0, next=None):
self.value = value
self.next = next
def hasCycle(head: ListNode) -> bool:
if not head or not head.next:
return False
slow = head
fast = head.next
while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
二、使用哈希表(集合)

这种方法的思想是利用哈希表(在Python中通常使用集合set)来记录已经访问过的节点。在遍历链表的过程中,每访问一个节点,就将其添加到哈希表中。如果在某个时刻遇到一个已经在哈希表中存在的节点,则说明链表中存在环。

算法步骤

  1. 创建一个空集合visited,用于存储已经访问过的节点。
  2. 初始化一个指针current,指向链表的头节点。
  3. 进入循环,条件是current不为null
  4. 在每次循环中,检查current是否已经在visited集合中:
    • 如果在,则链表中存在环,返回true
    • 如果不在,则将current添加到visited集合中,并将current移动到下一个节点(current = current.next)。
  5. 如果循环结束(即currentnull),则链表中不存在环,返回false

实现代码(Python):

class ListNode:
def __init__(self, value=0, next=None):
self.value = value
self.next = next
def hasCycleWithSet(head: ListNode) -> bool:
visited = set()
current = head
while current:
if current in visited:
return True
visited.add(current)
current = current.next
return False
三、算法分析

时间复杂度

  • 快慢指针方法:O(n),其中n是链表的长度。因为每个节点最多被访问两次(快指针每次移动两步)。
  • 哈希表方法:O(n),其中n是链表的长度。因为每个节点都被访问一次,并且被添加到哈希表中一次(在平均情况下,哈希表的插入和查找操作都是O(1)的)。

空间复杂度

  • 快慢指针方法:O(1),因为只使用了两个指针,没有使用额外的存储空间(不考虑递归栈或系统栈)。
  • 哈希表方法:O(n),在最坏情况下,需要存储链表中的所有节点。

适用场景

  • 快慢指针方法更节省空间,适用于内存受限的场景。
  • 哈希表方法更直观易懂,适用于对空间复杂度要求不高的场景。
四、注意事项
  • 在使用快慢指针方法时,需要确保快指针不会越界(即检查fastfast.next是否为null)。
  • 在使用哈希表方法时,需要注意哈希表的容量和冲突解决策略(但在Python的set中,这些通常由底层实现自动处理)。
  • 如果链表很长或节点数量未知,可能需要考虑使用迭代而不是递归来实现算法,以避免栈溢出。
五、总结

判断链表是否有环是一个经典的算法问题,可以使用快慢指针或哈希表来解决。这两种方法各有优缺点,在实际应用中应根据具体需求和场景进行选择。通过理解这两种方法的原理和实现过程,我们可以更好地掌握链表遍历和数据结构的基本概念,为解决更复杂的算法问题打下坚实的基础。

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

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

相关文章

Netty简单应用

1.服务端构建 接收客户端请求,打印请求消息;消息采用内置String作为编码与解码器;开启信息输入监听线程,发送消息至客户端; 1.1 服务端消息处理类 import io.netty.channel.Channel; import io.netty.channel.Chann…

双十一好物必买清单攻略,这几款双十一必入的宝藏好物分享

随着双十一购物节的脚步日益临近,无数消费者都在期待着在这个年度大促中抢购到自己心仪已久的好物,为了帮助大家更好地规划购物计划,精选出真正值得入手的宝藏产品,我们特别整理了这份双十一好物必买清单攻略,无论你是…

spring day1023

ok了家人们,今天继续学习spring框架, 七.Spring的注解开发 在开发中,配置文件中 Bean 标签会非常多,难以维护。怎么 办? 使用注解的形式替代 xml 配置,可以将一些繁杂的 spring 配置 从工程中消除掉&…

业余时间试一试利用AI 人工智能赚钱

内容创作与写作: 撰写文章:许多网站、博客和企业都需要大量的优质内容。利用 AI 工具如 ChatGPT 等,获取文章的思路、框架甚至初稿,然后根据自己的知识和经验进行修改、润色和完善。你可以在一些自由撰稿人平台、内容创作平台上承…

智能园艺:Spring Boot植物健康系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理植物健康系统的相关信息成为必然。开发合适…

es索引库操作和使用RestHignLevelClient客户端操作es

目录 es索引库操作 mapping映射操作 索引库的CURD操作 1.创建索引库和映射 ​编辑 2.查询索引库 3.删除索引库 4.修改索引库 5.总结 文档的CURD操作 1.新增文档 2.查询文档 3.删除文档 4.修改文档 全量修改 增量修改 5.总结 RestAPI 使用API例子 需要的数…

一文掌握异步web框架FastAPI(五)-- 中间件(测试环境、访问速率限制、请求体解析、自定义认证、重试机制、请求频率统计、路径重写)

接上篇:一文掌握异步web框架FastAPI(四)-CSDN博客 目录 七、中间件 15、测试环境中间件 16、访问速率限制中间件,即限制每个IP特定时间内的请求数(基于内存,生产上要使用数据库) 1)限制单ip访问速率 2)增加限制单ip并发(跟上面的一样,也是限制每个IP特定时间内的请…

大模型算法二次开发,基本思路详细拆解

[ 导读 随着众多大模型相继问世,大模型二次开发、大模型微调成为一项热门技术。本文为大家总结了大模型二次开发的基本方法与思路,希望对大家有所帮助。 开发方法分类 1、领域知识注入:Continue PreTraining(增量预训练),一般垂直大模型是…

(STM32笔记)十二、DMA的基础知识与用法

我用的是正点的STM32F103来进行学习,板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。 DMA的基础知识与用法 一、DMA功能框图1、DMA请求2、通道3、仲裁器 二、DMA传输设置1、数据来源与数据去向外设到存储器存储器…

Lua环境安装

软考鸭微信小程序 学软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 Lua是一种轻量级、小巧且易于嵌入应用程序的脚本语言,广泛用于游戏开发、Web开发、自动化脚本等领域。本文将详细介绍如何在不同操作系统上安装L…

蓝桥杯注意事项

蓝桥杯注意事项 比赛注意事项 能暴力枚举就暴力枚举,能用简单的思路做就尽量用简单的思路做。认真审核题目的题意和输入输出的要求,避免因为误解题意而导致题目错误。对于提供多组测试样例或者需要对一个过程重复进行循环的代码,要时刻记住…

六大设计原则之一——单一职责原则

单一职责原则 面向对象三大特性之一的 封装 指的就是将单一事物抽象出来组合成一个类,所以我们在设计类的时候每个类中处理的是单一事物而不是某些事物的集合。 设计模式中所谓的 单一职责原则(Single Responsibility Principle - SRP),就是对一个类而…

autMan奥特曼机器人-实时翻译的用法

一、基本配置 访问并登录百度翻译开放平台:https://api.fanyi.baidu.com/ 进入开发者信息获取 APP ID和密钥,并开通“通用文本翻译”服务 autMan应用市场->我的->找到“实时翻译”插件安装后去点击“配参” 二、使用示例 假如你和一个俄国人聊…

C程序设计语言精髓 单向链表

目录 单向链表---定义 单向链表---建立 单向链表---删除 单向链表---插入​ 单向链表---输出​ 单向链表---定义 单向链表---建立 单向链表---删除 单向链表---插入 单向链表---输出

Visual Studio安装图文详解教程

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 教程说明 本教程旨在详细介绍 Visual Studio 社区版的安装过程及其注意事项。 Visual Studio简介 Visual Studio 社区版功能完备且可扩展的免费 IDE,可用于创…

【通俗理解】Neurosymbolic AI——融合神经网络与符号推理的智慧之力

【通俗理解】Neurosymbolic AI——融合神经网络与符号推理的智慧之力 关键词提炼 #Neurosymbolic AI #神经网络 #符号推理 #感知能力 #逻辑能力 #认知水平 #智慧与力量 第一节:Neurosymbolic AI的类比与核心概念 Neurosymbolic AI就像是给神经网络这位“大力士”…

神策数据客户旅程 GPT:以 AI 驱动客户旅程及埋点落地

数据驱动时代,随着 AI 在数据处理及分析方面的能力日渐强大,将二者结合,可以帮助企业效能提升,获取更多商业价值。 我们在 AI 大模型探索过程中发现,产品经理、技术人员、市场营销人员以及需要数据驱动决策的团队&…

基于opencv的人脸闭眼识别疲劳监测

1. 项目简介 本项目旨在实现基于眼部特征的眨眼检测,通过监测眼睛开闭状态来计算眨眼次数,从而应用于疲劳监测、注意力检测等场景。使用了面部特征点检测算法,以及眼部特征比率(EAR, Eye Aspect Ratio)来判断眼睛的闭…

可观测日北京|观测云:可观测性需要做到“三个一”

2024年10月,备受期待的中国可观测日「北京站」圆满落幕。本次活动汇聚了来自云计算、技术创新等领域的专家,探讨了探讨了可观测性在云计算和数字化转型中扮演的角色。观测云也在活动展示了作为可观测性行业领袖的技术力和创新力。 观测云技术亮点&#…

python画图|坐标轴显隐设置

【1】引言 前序学习中,已经发现坐标轴的显示具有至关重要的影响,因此今天继续探索相关技巧:坐标轴显隐设置。 前序学习内容可通过下述链接直达: python画图| 对齐图名和标签-CSDN博客 【2】官网教程 点击下方链接可以直达官网…