快乐数定义与示例
在数字的世界里,有一种特殊的正整数被称为'快乐数'。它的判定规则很简单:将该数的各位数字平方求和,得到一个新数;再对新数重复此操作。如果最终能收敛到 1,它就是快乐数;如果陷入一个不包含 1 的循环,则是不快乐数。
以 19 为例,这个过程如下:
19 → 1² + 9² = 82
82 → 8² + 2² = 68
68 → 6² + 8² = 100
100 → 1² + 0² + 0² = 1
经过 4 步变换,19 到达了终点 1,因此它是快乐数。
核心思路:从数字到链表
虽然处理的是数字,但我们可以换个角度思考。如果把每个数字看作链表中的一个节点,把'平方和变换'看作指向下一个节点的指针,那么快乐数问题就转化为了经典的链表判环问题。
对于快乐数,路径最终指向 1 并结束(相当于 null);对于不快乐数,路径会形成一个闭环。
算法实现:快慢指针
解决链表判环最经典且高效的方法是快慢指针(Floyd 判圈算法)。
- 慢指针:每次走一步,计算一次平方和。
- 快指针:每次走两步,连续计算两次平方和。
如果存在环,快慢指针终将相遇;如果不存在环(即快乐数),快指针会率先到达 1。
C++ 代码解析
首先需要一个辅助函数来计算单个数字的平方和:
int getNext(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
主逻辑利用快慢指针进行遍历:
bool isHappy(int n) {
int slow = n;
int fast = getNext(n);
// 当快指针未到 1 且快慢指针未相遇时继续
while (fast != 1 && slow != fast) {
slow = getNext(slow);
fast = getNext(getNext(fast));
}
return fast == 1;
}
注意这里快指针先走了一步,这样初始化后两者位置不同,便于进入循环判断。


