🧠 小哆啦解题记 —— 谁偷走了我的快乐?

📅 小哆啦刷题 Day 37

题号:202. 快乐数 - 力扣(LeetCode)

关键词:数位平方和、哈希判环、数学循环论证、无限循环解释


第一章:大雄的灵魂发问

"哆啦A梦,最近怎么也开心不起来......难道我......不是个快乐数?"

大雄满脸迷茫地趴在课桌上。

哆啦A梦吃着铜锣烧冷静回答:"来,我带你刷一道题,看看你到底'快乐不快乐'。"


第二章:题目来了

给你一个正整数 n,重复如下操作:

  • 将其每一位数字的平方求和,得出新数。
  • 不断重复此过程。

如果最终可以变成 1,就是快乐数

如果陷入无限循环 却始终得不到 1,那就很遗憾,它不是快乐数


第三章:大雄的第一版代码(带点 Bug)

typescript 复制代码
function isHappy(n: number): boolean {
    let numMap: Map<number, number> = new Map();
    while (true) {
        let str = n.toString();
        n = str.split("").reduce((acc, cur) => acc + Math.pow(Number(cur), 2), 0);
        if (n == 1) return true;
        if (numMap.has(n)) return false;
        numMap.set(Number(str), n);
    }
}

"我每出现一个数就记录一下,如果又出现了,说明在无限转圈。"大雄自信地说。

哆啦A梦一边擦眼镜一边点头:"嗯......基本思路对,但你这 Map 存得太复杂,Set 更合适。"


第四章:哆啦A梦的快乐优化器

于是他甩出优化后的版本:

ini 复制代码
function isHappy(n: number): boolean {
    const seen = new Set<number>();
    while (n !== 1) {
        if (seen.has(n)) return false;
        seen.add(n);
        n = getNext(n);
    }
    return true;
}

function getNext(num: number): number {
    let sum = 0;
    while (num > 0) {
        const digit = num % 10;
        sum += digit * digit;
        num = Math.floor(num / 10);
    }
    return sum;
}

"每次记录出现过的数,只要你再走进来一次,就说明------你在绕圈。"


第五章:大雄困惑了:为什么就一定会循环?

"等等等等......你说 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 是循环,那为啥一定会循环?为啥不能一直变大,或者跑到 1e10?"

哆啦A梦收起铜锣烧,郑重地回答:


🧠 第六章:无限循环的数学机制,正式揭晓

🧩 一、每一步"变换"都有上限!

你以为这些数字会无限增长?错!

👉 最大增长速率远小于原数值本身。

比如一个 4 位数 9999,变换后是:

ini 复制代码
9² + 9² + 9² + 9² = 81 × 4 = 324

✨ 所以,不管你是 999999999 还是 9999,最终都收敛到一个相对较小的数。

实验证明:任意正整数,变换后最终都会收敛到 ≤ 243。

所以你最多只会经历 243 个不同状态,一旦遇到重复,就铁定进入循环!


🌀 二、经典环:不快乐循环的"死亡八卦阵"

试试 n = 2,看它怎么绕回自己:

erlang 复制代码
2 → 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 ...

恭喜,它回到 4 了,这就是经典的"非快乐数死循环"


第七章:进阶姿势·快慢指针

如果你不想用额外空间,那就用链表判环那一套------快慢指针

ini 复制代码
function isHappy(n: number): boolean {
    let slow = n, fast = getNext(n);
    while (fast !== 1 && slow !== fast) {
        slow = getNext(slow);
        fast = getNext(getNext(fast));
    }
    return fast === 1;
}

就像两只赛跑的仓鼠,一快一慢在圆环里转,如果能碰头,就说明陷入循环了。


第八章:终章·算法与人生的哲学

静香眨了眨眼:"那你们说,人类的快乐,是不是也能像这样判定?"

哆啦A梦认真回答:"如果你重复做一些事,却永远得不到满足,可能你已经掉进了非快乐循环。"


✅ 小哆啦的技术小结

解法 判环方式 时间复杂度 空间复杂度 特点
哈希表判环 Set 记录状态 O(logN) O(logN) 简单直观,好调试
快慢指针 空间优化 O(logN) O(1) 进阶思维,链表判环思想迁移

🎓 总结一句话

不是每一个数都有快乐结局,但每一个循环都有逃出生天的可能。

相关推荐
花火|33 分钟前
算法训练营day62 图论⑪ Floyd 算法精讲、A star算法、最短路算法总结篇
算法·图论
GuGu202441 分钟前
新手刷题对内存结构与形象理解的冲突困惑
算法
汤永红43 分钟前
week4-[二维数组]平面上的点
c++·算法·平面·信睡奥赛
晴空闲雲1 小时前
数据结构与算法-字符串、数组和广义表(String Array List)
数据结构·算法
颜如玉3 小时前
位运算技巧总结
后端·算法·性能优化
冷月半明3 小时前
时间序列篇:Prophet负责优雅,LightGBM负责杀疯
python·算法
秋难降3 小时前
聊聊 “摸鱼式” 遍历 —— 受控遍历的小心机
数据结构·算法·程序员
等风来不如迎风去4 小时前
【动态规划】309. 买卖股票的最佳时机含冷冻期及动态规划模板
算法·动态规划
小xin过拟合7 小时前
day20 二叉树part7
开发语言·数据结构·c++·笔记·算法
lxmyzzs8 小时前
【图像算法 - 23】工业应用:基于深度学习YOLO12与OpenCV的仪器仪表智能识别系统
人工智能·深度学习·opencv·算法·计算机视觉·图像算法·仪器仪表识别