zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    
  • 相关阅读:
    Redis简单实践-分布式锁
    Redis基础数据结构
    Redis介绍
    MakeGenericType方法,运行时传入泛型T参数,动态生成泛型类
    Visual Studio 2017 Ctrl+单击键会跳转到定义的设置
    10 分钟 创建分布式微服务
    nodejs 中自定义事件
    我是这么给娃娃取名的(使用 node.js )
    使用 Fiddler 上传微信公众账号 自定义菜单
    drf_yasg 简单使用
  • 原文地址:https://www.cnblogs.com/Elaine-DWL/p/9851232.html
Copyright © 2011-2022 走看看