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;
    }
};

原文地址:https://www.cnblogs.com/Elaine-DWL/p/9851232.html

时间: 2024-10-06 23:22:51

Floyd判圈算法(判断链表是否含环)的相关文章

Floyd判圈算法(判断是否有环)

介意转吗博主~~http://blog.csdn.net/thestoryofsnow/article/details/6822576,我知道不介意啦~ 问题:如何检测一个链表是否有环,如果有,那么如何确定环的起点. 龟兔解法的基本思想可以用我们跑步的例子来解释,如果两个人同时出发,如果赛道有环,那么快的一方总能追上慢的一方.进一步想,追上时快的一方肯定比慢的一方多跑了几圈,即多跑的路的长度是圈的长度的倍数. 基于上面的想法,Floyd用两个指针,一个慢指针(龟)每次前进一步,快指针(兔)指针每

Floyd判圈算法

Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机.迭代函数或者链表上判断是否存在环,求出该环的起点与长度的算法.该算法据高德纳称由美国科学家罗伯特·弗洛伊德发明,但这一算法并没有出现在罗伯特·弗洛伊德公开发表的著作中.  如果有限状态机.迭代函数或者链表上存在环,那么在某个环上以不同速度前进的2个指针必定会在某个时刻相遇.同时显然地,如果从同一个起点(即使这个起

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

Write an algorithm to determine if a number is "happy". 写出一个算法确定一个数是不是快乐数. A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat th

[LeetCode] 287. Find the Duplicate Number(Floyd判圈算法)

传送门 Description Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Note: You mu

uva 11549计算器谜题(floyd判圈算法)

 题意:有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 思路:这个题一定会出现循环,所以一个个模拟,遇到相同的就再之前所有数中找最大的输出即可. 最容易想到的就是set判重,一开始k直接生算每次除十......超时 然后看了书,用string,ac,很方便但是时间达到了4s,果然string和stringstream好慢啊......... 又改成了记录k*k的每一位,

SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slower than the same code written in C++ or Java. We do not gua

sgu 455. Sequence analysis (floyd 判圈算法,O(1)空间复杂度求循环节)

455. Sequence analysis Time limit per test: 1 second(s)Memory limit: 4096 kilobytes input: standardoutput: standard Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slow

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

https://vjudge.net/problem/UVA-11549 题意: 有一个老式计算器,只能显示n位数字,输入一个整数k,然后反复平方,如果溢出的话,计算器会显示结果的最高n位.如果一直这样做下去,能得到的最大数是多少? 思路: 这个肯定是会循环的. 比较普通的做法就是用set来判断是否出现过来终止循环. 另一个高效算法:Floyd判圈算法!! 想象一下,假设有两个小孩子在一个“可以无限向前跑”的跑道上赛跑,同时出发,但其中一个孩子的速度是另一个两倍.如果跑到是直的,跑得快的小孩永远

UVA11549 计算机谜题(Floyd判圈算法)

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<set> 7 #include<sstream> 8 using namespace std; 9 /*int next1(int n,int k) 10 { 11 stringstream ss; 12