Floyd判圈算法(判断链表是否含环)

Posted elaine-dwl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Floyd判圈算法(判断链表是否含环)相关的知识,希望对你有一定的参考价值。

Floyd判圈算法

简介

Floyd判圈算法,也称龟兔赛跑算法,可用于判断链表、迭代函数、有限状态机是否有环。如果有,找出环的起点和大小。时间复杂度O(n),空间复杂度O(1)。

可以先思考一下,假设有一个圆形的跑道周长为(C),A和B从同一个起点,分别以(v)(2v)的速度同向出发,可以知道,因为B比A跑得快而且跑道是环形的,所以接下来一定存在某一时刻,B和A相遇,这时候,B跑过的总距离(S_B)减去A跑的总距离(S_A)一定是(C)的整数倍。即: (S_B-S_A = k*C, k=1,2,...)

算法思路

在判断链表是否有环的问题中,可以使用Floyd算法来判断。

使用2个指针,一个快(fast)一个慢(slow),初始化两个指针在起始位置。每次fast向前走两步,slow向前走一步。若fast到达了终点,则证明链表中有环。若fast和slow再次相遇,则说明链表中含环。

例题

leetcode202. Happy Number

题意:
判断某个数字是不是happy number.
happy number满足一下几点:
以任意正整数开头,用它各个位置上数字的平方和生成一个新的数字。
对于该新的数字,重复上述步骤,如果最后生成的数字是1。则原始数字是happy number。
解法一:
借助set容器,每次生成的数字放入set中,如果出现了重复,即说明出现了循环,则该数字不是happy number.
解法二:
等价于判断是否有环。用Floyd算法判断是否有环。

解法二代码:

class Solution{
public:
    int cal(int n){
        string s=to_string(n);
        int sum=0;
        for(char num:s){
            sum += (num-‘0‘)*(num-‘0‘);
        }
       // cout<<"sum: "<<sum<<endl;
        return sum;
    }
    bool isHappy(int n){
        int slow=n, fast=n;// 初始化
        while(slow!=1 && fast!=1){
            slow = cal(slow);// 走一步
            if(slow==1) return true;
            fast = cal(cal(fast));//走两步
            if(slow==fast) return false;
        };
        return true;
    }
};








以上是关于Floyd判圈算法(判断链表是否含环)的主要内容,如果未能解决你的问题,请参考以下文章

Floyd判圈算法 Floyd Cycle Detection Algorithm

Floyd 判圈算法

UVa 11549 计算器谜题(Floyd判圈算法)

弗洛伊德的乌龟与兔子

Floyd判圈算法

leetcode202(Floyd判圈算法(龟兔赛跑算法))