题目描述
思路解析动画文字版
无限模拟不知道什么时候停。
状态不是到 1 就会进入循环;用 seen 集合或快慢指针检测循环。
1. 反复求「数位平方和」:快乐数:反复把 n 换成它各数位的平方和,能到 1 就是快乐数。对 19:1²+9²=82,并把 19 记入 seen。
2. 82 → 68:对 82:8²+2²=68。82 记入 seen。
3. 68 → 100:对 68:6²+8²=100。
4. 100 → 1:对 100:1²+0²+0²=1。
5. 到 1 → 快乐数 true:链走到 1 → 19 是快乐数,返回 true。
6. 关键帧 · 为什么一定会停:关键帧:不快乐的数会陷入固定循环 4→16→37→58→89→145→42→20→4,永远到不了 1。所以规则只有两种结局:到 1(快乐) 或 seen 命中重复(循环→不快乐)。数位平方和会把大数迅速压小(3 位数最大 243),落入有限范围必然重复或到 1。
一句话记住:状态不是到 1 就会进入循环;用 seen 集合或快慢指针检测循环。
边界三连:三种边界先想清楚。
面试追问 1:核心思路+两种检测。
面试追问 2:为什么一定终止。
面试追问 3:O(1) 空间优化。
这题学完不要乱跳,下一步去对应专题 /leetcode-animation/ds?k=math 连刷同类题;卡住时用 AI 答疑问“我的状态定义哪里不稳”。
参考代码
class Solution: def isHappy(self, n): def square_sum(x): s = 0 while x: x, d = divmod(x, 10) s += d * d # 累加各数位平方 return s seen = set() while n != 1 and n not in seen: seen.add(n) n = square_sum(n) return n == 1 # 到 1 快乐;否则陷入循环复杂度
- 时间复杂度:O(log n),数位平方和让数字迅速变小,迭代次数有界
- 空间复杂度:O(log n),seen 集合存途经的数;用快慢指针可降到 O(1)
可套用的代码模板
骨架就是模拟链 + 用 seen 判圈:到 1 快乐,重复出现就是循环。
Python
# 快乐数骨架 · 模拟 + 判圈seen = set()while n != 1 and n not in seen: seen.add(n) n = 各数位平方和(n) # 关键转移return n == 1 # 到 1 快乐;命中 seen 是循环易错点
面试追问把动画讲成自己的话
追问核心思路是什么?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
加一
LeetCode 66 · 简单 · 沿着 数学 & 几何 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题