• 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;
        }
    };
    
  • 相关阅读:
    使用路由传参时,query与params的区别!
    写前端页面步骤----vue+iview
    使用vue做表单验证
    vue中find函数
    @Controller和@RestController的区别?
    JavaScript 拥有动态类型
    Console的9种用法
    Navicat连接Oracle报ORA-12737错误
    oracle查询数据库连接数相关
    oracle存储过程把查询到的值更新到别的表
  • 原文地址:https://www.cnblogs.com/Elaine-DWL/p/9851232.html
Copyright © 2020-2023  润新知