【leetcode刷题日记】202.快乐数

老规矩,先康康力扣官方的题目描述吧

编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环
但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

这个题其实很简单,只需要分析快乐数的几种情况就行了
咱们分析一下快乐数的几种情况

1.一直循环下去最后变为1
2.陷入无限循环
3.一直在无限变大,最后变得无穷大

其中前两个是非常容易理解的,但是第三个情况是需要分析一下的
首先咱们要明白一个理论:n的平方根肯定比比n小的数的平方根大
所以,假设要分析的快乐数num是个三位数,那么这个num的最大值就是999,经过一次循环之后就变成了92+92+92=243,也就是比num小的数经过一次循环之后的数也不可能超过243

所以,第三种情况不存在

现在思路已经分析透彻了,现在就是解决方法的使用。我一时间只想到了两个比较好的实现方法
一个是利用hash表来存储所有出现过的数字,只要出现相同的数字且不为1就代表这个快乐数陷入了无限循环
另一个方法是使用快慢指针的方法,当快指针与慢指针相遇即代表这个快乐数陷入了无限循环

使用hash表比较浪费内存空间,所以使用快慢指针来进行编写
代码如下

class Solution {
public:
    bool isHappy(int n) 
    {
        int low=n,fast=beHappy(n);
        while(true)
        { 
            if((low==1||fast==1))//当快乐数循环到1停止
            {
                return true;
            }
            else if(low==fast)//当快慢指针相遇表示陷入无限循环
            {
                return false;
            }

            low=beHappy(low);
            fast=beHappy(beHappy(fast));
        }
        return true;
    }
    //快乐一次的函数,进行一次循环
    int beHappy(int n)
    {
        int ans=0;
        while(n)
        {
            ans+=(n%10)*(n%10);
            n/=10;
        }
        return ans;
    }
};

你可能感兴趣的:(leetcode刷题日记,leetcode,算法)