弗洛伊德循环查找算法-原理

news2024/10/1 23:49:35

本文灵感来自哔哩哔哩视频 

视频链接:

弗洛伊德循环查找算法

算法代码(java)

package rain;

class ListNode {
    int value;
    ListNode next;

    public ListNode(int value) {
        this.value = value;
        this.next = null;
    }

    @Override
    public String toString() {
        return "ListNode{" +
                "value=" + value +
                '}';
    }
}
public class FloydCycleDetectionAlgrithm {
    public static void main(String[] args) {
        ListNode node0 = new ListNode(4);
        ListNode node1 = new ListNode(3);
        ListNode node2 = new ListNode(7);
        ListNode node3 = new ListNode(8);
        ListNode node4 = new ListNode(6);
        ListNode node5 = new ListNode(9);
        ListNode node6 = new ListNode(2);
        ListNode node7 = new ListNode(1);
        ListNode node8 = new ListNode(5);
        ListNode node9 = new ListNode(2);

        node0.next = node4;
        node1.next = node3;
        node2.next = node7;
        node3.next = node8;
        node4.next = node6;
        node5.next = node9;
        node6.next = node2;
        node7.next = node1;
        node8.next = node5;
        node9.next = node2;

        ListNode node = Find(node0);
        System.out.println(node);
    }
    public static ListNode Find(ListNode head) {
        ListNode slow  = head;
        ListNode fast = head;

        while (true) {
            slow = slow.next;
            fast = fast.next.next;
            //第一次相遇
            //if slow and fast meet, then break the loop
            if (fast == slow) {
                break;
            }
        }
        //第二次相遇
        slow = head;
        while (true) {
            slow = slow.next;
            fast = fast.next;
            if (fast == slow) {
                return fast;
            }
        }
    }
}

弗洛伊德循环查找算法中第二次相遇的地方就是循环的起始点,这个性质的证明是基于数学的原理。这是因为在第一次相遇时,慢指针 `slow` 和快指针 `fast` 已经处于同一个循环内。设链表起点到环的起始点的距离为 X,环的起始点到第一次相遇点的距离为 Y,第一次相遇点到环的起始点的距离为Z。

第一次相遇

 ListNode slow  = head;
        ListNode fast = head;

        while (true) {
            slow = slow.next;
            fast = fast.next.next;
            //第一次相遇
            //if slow and fast meet, then break the loop
            if (fast == slow) {
                break;
            }
        }

设循环长度

1. 在第一次相遇时,慢指针 `slow` 走的距离,

C2是常数

而快指针 `fast` 走 的距离

2. 由于快指针的速度是慢指针的两倍,所以快指针走的距离是慢指针的两倍。因此,有

3. 进一步简化上述等式,得到

这意味着

循环前的距离X = 一定数量循环次数 减去 汇合点前距离Y

4.因为

可得

C3乘以 循环长度长度l 意味着固定的循环量!

找到节点只需要让两个节点分别走X和C3l+Z的路程

此时, 我们可以把slow放在起始位置 每次走一格, 

同时 让fast也是每次走一格

直到相遇 fast == slow 说明相遇的节点就是循环开始的节点

//第二次相遇
        slow = head;
        while (true) {
            slow = slow.next;
            fast = fast.next;
            if (fast == slow) {
                return fast;
            }
        }

也就是说,如果此时将慢指针重新指向链表起始点,慢指针再次移动 X 的距离,而快指针从第一次相遇点开始移动 C3l+Z 的距离,它们将会在环的起始点再次相遇。

因此,第二次相遇的地方就是循环的起始点。这个性质是弗洛伊德循环查找算法的关键之一,也是该算法能够正确找到环的起始点的原因。

文末推荐我常用的一个学习网站 可视化运行程序

比如这段链表就可以直观展示出来

网站链接

可视化运行网站

 

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

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

相关文章

Kotlin 移动端多平台

支持多平台编程是 Kotlin 的主要优势之一。它减少了为不同平台编写和维护相同代码所花费的时间,同时保留了本机编程的灵活性和优势。 1. 基本概念 KMM:Kotlin Multiplatform for mobile(移动设备的 Kotlin 多平台) KMM 多平台的主…

使用的uview 微信高版本 头像昵称填写能力

<template><view><button class"cu-btn block bg-blue margin-tb-sm lg" tap"wxGetUserInfo">一键登录</button><view><!-- 提示窗示例 --><u-popup :show"show" background-color"#fff">&…

pygame里实现导弹追踪效果,同时对python的指针机制有一点点思考

最近,儿子一直缠着让我把之前给他编写的游戏重做一下,要加一些功能.但是因为之前写代码的时候刚学会python,当时的想法就是能跑就行,现在回头看来,代码的可维护性几乎为零.所以没办法只能冲头再来,重构了几乎所有代码.在编写的时候遇到了一个有意思的问题,儿子让我给游戏添加一…

Pyside6入门教学——编写一个UI界面并显示

1、安装Pyside6 输入下列命令安装Pyside6。 pip install Pyside6 2、设计UI 打开Qt设计工具&#xff08;在安装Pyside6包的目录下&#xff09;。 【注】我这用的是anaconda虚拟环境&#xff0c;所以我的路径是D:\App\Anaconda3\envs\snake\Lib\site-packages\PySide6。设计…

【Python学习】Python学习19- 异常处理

目录 【Python学习】Python学习19- 异常处理 前言python标准异常异常处理带异常类型语法不带异常类型语法使用except而带多种异常类型try-finally 语句触发异常 参考 文章所属专区 Python学习 前言 本章节主要说明Python的异常处理。 python标准异常 BaseException 所有异常…

GNU Radio简介及流程图搭建

文章目录 前言一、GNU Radio 是什么&#xff1f;二、GNU Radio 安装三、搭建第一个流程图1、创建 GRC 文件2、添加块3、运行流程图 前言 欢迎来到无线通信的世界&#xff0c;初步接触 GNU Radio&#xff0c;对其学习进行一个记录。 一、GNU Radio 是什么&#xff1f; GNU Rad…

【C语言编程之旅 4】刷题篇-关键字

第一题 解析 C语言关键字&#xff1a;C语言定义的&#xff0c;具有特定含义、专门用于特殊用途的C语言标识符&#xff0c;也称为保留字 A&#xff1a;错误&#xff0c;关键字是语言自身定义的 B&#xff1a;正确 C&#xff1a;错误&#xff0c;关键字具有特殊含义&#xff…

docker部署项目,/var/lib/docker/overlay2目录满了如何清理?

docker部署项目&#xff0c;/var/lib/docker/overlay2目录满了如何清理&#xff1f; 一、问题二、解决1、查看 /var/lib/docker 目录&#xff08;1&#xff09;、containers 目录&#xff08;2&#xff09;、volumes 目录&#xff08;3&#xff09;、overlay2 目录 2、清理&…

Java开发分析 JProfiler 14 中文

JProfiler 14是一款强大的Java分析工具&#xff0c;专为帮助Java开发者优化应用性能而设计。它提供了实时监控、内存分析、线程分析、CPU分析等多种功能&#xff0c;帮助开发者快速定位和解决性能问题。JProfiler 14具有直观的用户界面&#xff0c;使用户能够轻松上手。此外&am…

苹果Find My可查找添加32件物品,伦茨科技ST17H6x芯片加速产品赋能

苹果最近更新的支持文档证实&#xff0c;从 iOS 16 开始&#xff0c;"Find My"可查找添加物品从16件增加到32件&#xff0c;AirTag 和“查找”网络中的物品利用“查找”网络的强大功能来发挥作用&#xff0c;这个网络由数亿台加密的匿名 Apple 设备构成。“查找”网络…

Kafka-多线程消费及分区设置

目录 一、Kafka是什么&#xff1f;消息系统&#xff1a;Publish/subscribe&#xff08;发布/订阅者&#xff09;模式相关术语 二、初步使用1.yml文件配置2.生产者类3.消费者类4.发送消息 三、减少分区数量1.停止业务服务进程2.停止kafka服务进程3.重新启动kafka服务4.重新启动业…

PPT大神带你飞!!!

1、OneKeyTools 官网&#xff1a;http://oktools.xyz/ OneKeyTools是一款免费开源的PowerPoint第三方平面设计辅助插件&#xff0c;功能涵盖了形状、调色、三维、图片处理、辅助功能等等方面。 插件功能&#xff1a; 插件从面世逐步受到广大PPT设计师和爱好者的追捧&#x…

感谢大家的支持,继续耕耘

有什么大家感兴趣的领域&#xff0c;欢迎留言

SSH数据流量监控

简介 检查网络连接的数据传输情况有以下一些实际意义&#xff1a; 安全监控&#xff1a;检查数据传输情况可以帮助你识别异常活动或潜在的安全威胁。如果发现大量不寻常的数据传输活动&#xff0c;可能表示有未经授权的访问或恶意行为。通过监控数据传输&#xff0c;可以及时发…

软件测评中心▏正式验收测试和非正式验收的优缺点简析

软件正式验收测试需要非常严格的管理&#xff0c;是对系统测试的延续&#xff0c;这种验收测试的测试用例应是系统测试的子集。非正式验收测试不像正式验收测试那么严格&#xff0c;不需要执行指定的测试用例&#xff0c;可以由测试人员自主决定&#xff0c;但制定测试用例时必…

node.js(express.js)+mysql实现登录功能

文章目录 前言实现步骤 实现步骤一、检测登录表单的数据是否合法&#xff08;3&#xff09;新建schema/user.js&#xff08;4&#xff09;在routes/use.js中引入schema/user.js中的方法reg_login_schema&#xff0c;代码如下&#xff1a; 二、根据用户名查询用户的数据三、判断…

浅析Redis①:命令处理核心源码分析(上)

写在前面 Redis作为我们日常工作中最常使用的缓存数据库&#xff0c;其重要性不言而喻&#xff0c;作为普调开发者&#xff0c;我们在日常开发中使用Redis&#xff0c;主要聚焦于Redis的基层数据结构的命令使用&#xff0c;很少会有人对Redis的内部实现机制进行了解&#xff0c…

C++:类与结构体的对比

2024年1月18日 内容来自The Cherno:C系列 -------------------------------------------------------------------------------------------------------------------------------- C中关于class与struct&#xff0c;几乎没有区别&#xff0c;只有一个关于“可见度”的区别…

Go 爬虫之 colly 从入门到不放弃指南

文章目录 概要介绍如何学习官方文档如何安装快速开始如何配置调试分布式代理层面执行层面存储层面存储多收集器配置优化持久化存储启用异步加快任务执行禁止或限制 KeepAlive 连接扩展总结如果想用 GO 实现爬虫能力,该如何做呢?抽时间研究了 Go 的一款爬虫框架 colly。 概要…

【前后端的那些事】15min快速实现图片上传,预览功能(ElementPlus+Springboot)

文章目录 Element Plus SpringBoot实现图片上传&#xff0c;预览&#xff0c;删除效果展示 1. 后端代码1.1 controller1.2 service 2. 前端代码2.1 路由创建2.2 api接口2.2 文件创建 3. 前端上传组件封装 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&…