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再次相遇,则说明链表中含环。
例题
题意:
判断某个数字是不是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判圈算法(判断链表是否含环)的主要内容,如果未能解决你的问题,请参考以下文章