当前位置: 首页 > news >正文

Floyd判圈算法(Floyd Cycle Detection Algorithm)

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
👀👀👀 个人博客:小奥的博客
👍👍👍:个人CSDN
⭐️⭐️⭐️:Github传送门
🍹 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
📜 欢迎点赞收藏关注哟! ❤️

文章目录

  • 一、基础概念
  • 二、检测是否有环
  • 三、查找环的入口
  • 四、求环的长度

一、基础概念

Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一种用于检测有限状态机、迭代函数或链表结构中是否存在环路的算法。该算法不仅能判断环的存在性,还可确定环的起点位置及其长度。

算法采用双指针策略,通过不同移动速度的指针遍历数据结构,根据指针相遇情况判定环路特征。

  • 时间复杂度$ O(n) $
  • 空间复杂度$ O(1) $

初始化:

  • 快慢指针:fast = slow = head
  • 单列表节点定义:
from typing import Optionalclass Node:"""单链表节点定义"""__slots__ = ("val", "next")def __init__(self, val: int, nxt: "Optional[Node]" = None):self.val = valself.next = nxt

二、检测是否有环

  1. 慢指针每次前进一步:slow = slow.next
  2. 快指针每次前进两步:fast = fast.next.next
  3. 快慢指针相遇(slow == fast),则链表中必含环;否则无环。

为什么有环快慢指针一定能相遇?

若存在环,快指针相对于慢指针速度为1步/轮,必然会在环内相遇。

# -------------------------------------------------
# 1. 探测是否有环(返回相遇节点或 None)
# -------------------------------------------------
def detect_cycle(head: Optional[Node]) -> Optional[Node]:"""Floyd 第一阶段:龟兔赛跑"""slow = fast = headwhile fast and fast.next:slow = slow.next          # 1 步fast = fast.next.next     # 2 步if slow is fast:          # 指针同一对象return slow           # 返回相遇点return None                   # 无环

三、查找环的入口

  1. 相遇后,让慢指针slow回到头结点,另一指针fast停在相遇点:slow=head
  2. 之后让慢指针slow继续走,并从头结点开始记录距离:slow=slow.next, head=head.next
  3. 两个结点再次相遇的节点为环的入口
# -------------------------------------------------
# 2. 定位环入口(若无环返回 None)
# -------------------------------------------------
def find_cycle_entry(head: Optional[Node]) -> Optional[Node]:meet = detect_cycle(head)if meet is None:return None# 第二阶段:同步一步一步走slow = headwhile slow is not meet:slow = slow.nextmeet = meet.nextreturn slow      # 或 meet,二者同一节点

四、求环的长度

方法 1:单指针绕环一周(最常用)

  1. 任选环内一个节点,记为 p(可用入口节点,也可用第一次相遇点)。
  2. 令 q = p.next,计数器 cnt = 1。
  3. 当 q ≠ p 时循环
    q = q.next;cnt++。
  4. 返回 cnt。
    结论:cnt 就是环长度 L。
    时间 O(L),空间 O(1)。
    —— 这就是最简洁的“公式”L = 单次遍历回到起点的步数

方法 2:双指针再跑一次“龟兔”——一次就同时求出 L 与验证
(如果忘记保存入口节点,或者想再练一次快慢指针,可以用这个变种)

  1. 在第一次相遇点后,保持慢指针不动,把快指针重新指向相遇点。
  2. 快指针每次走 1 步,计数器 cnt = 0。
  3. 循环直到两指针再次相遇:
    fast = fast.next;cnt++。
  4. 返回 cnt。
    结论:cnt 就是 L。
    原理:相对速度为 0,快指针恰好多跑一整圈。
# -------------------------------------------------
# 3. 计算环长度(若无环返回 0)
# -------------------------------------------------
def cycle_length(head: Optional[Node]) -> int:meet = detect_cycle(head)if meet is None:return 0# 方法 1:单指针绕环一周# cur, cnt = meet.next, 1# while cur is not meet:#     cur = cur.next#     cnt += 1# return cnt# 方法 2:把 fast 重新指向 meet,两者都一次一步slow = meetfast = meet.next        # 相对距离 1cnt = 1                 # 已经隔开 1 步while slow is not fast:fast = fast.next    # 每次一步cnt += 1return cnt
http://www.dtcms.com/a/512392.html

相关文章:

  • 网站建设支付宝温州建设学校网站
  • 深圳网站制作 优选灵点网络前端开发语言有哪些
  • .NET8 通过自定义类映射appsettings.json 文件某个节点的配置
  • 25-DAPO: An Open-Source LLM Reinforcement LearningSystem at Scale
  • 6个网站建设网站设置保存登录密码怎么取消
  • 网站建设和维护的职责网站开发工程师有证书考试吗
  • 网站建设计算机人员招聘策划营销方案
  • 《i.MX6ULL LED 驱动实战:内核模块开发与 GPIO 控制》
  • Effective Java学习笔记:用静态工厂方法代替构造器(第一条)
  • TDengine 数学函数 POW 用户手册
  • AI大模型“战国策”:主流LLM平台简单介绍
  • Prometheus监控部署——pushgateway自动推送
  • 网站布局优化问问建设网站的人
  • 做网站宜宾深圳龙华网站建设公司
  • vue3 setup的平级函数(宏函数)
  • 企业门户网站开发代码游戏公司网站模板下载
  • 基于MATLAB的证件照片背景变换实例
  • 网站模板资源
  • 网站开发与托管协议诚信通旺铺网站建设
  • 做a图片网站公众号涨粉
  • 安卓实例——统一动画
  • 数字化转型:概念性名词浅谈(第七十三讲)
  • 【推荐系统】快手OneSearch 提升3.2%订单量
  • jsp做的网页是网站吗三亚网红
  • 网页浏览器图标电商网站如何优化
  • 几种常用关系型数据库详细介绍
  • R-CNN详解
  • 网站维护要求哈尔滨网站建设效果
  • 多线程:线程类的方法做什么
  • 网站快速备案安全开发公司抽奖送房