【Leetcode202】快乐数——Floyd 判圈算法

同题上一篇:基于集合的方案

题目描述

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

思路与算法

代码

class Solution:

    def isHappy(self, n: int) -> bool:
        # 计算n的每位数字的平方和
        def next_num(n:int) -> int:
            return sum(int(digit)**2 for digit in str(n))
        
        slow = fast = n
        
        # 如果快慢指针相遇,说明形成环
        while fast != 1:
            slow = next_num(slow)
            fast = next_num(next_num(fast))
            if slow == fast:
                return fast == 1

        return True

总结

  1. 使用两个指针(或称快慢指针)同时在序列中移动。慢指针一次移动一步,而快指针一次移动两步。如果序列中存在循环,则快指针必然会在某个时刻追上慢指针(套圈);如果没有循环,快指针会先到达终点。
  2. 使用快慢指针(Floyd 判圈算法)不需要额外空间,适用于检测链表循环等场景,也是判断无限循环的常见技巧。
  3. 在使用 Floyd 判圈算法时,为防止初始状态下快慢指针相同而产生误判,可以采用两种常见方法:
    • 初始化时让快指针先走一步:将快指针设置为 head.next,从而保证初始时快慢指针不在同一位置,但需要注意边界条件(例如链表为空或只有一个节点的情况)。
    • 从同一起点开始,但在循环内先移动再比较:快慢指针均从 head 开始,在每次循环中先更新指针位置(快指针走两步,慢指针走一步),再进行比较,这样可以避免初始时误判。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值