老规矩,先康康力扣官方的题目描述吧
编写一个算法来判断一个数 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;
}
};