跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

LeetCode 202 快乐数:快慢指针解法详解

快乐数是指一个正整数经过各位数字平方和的反复替换后最终能变为 1 的数。若无法变为 1 则陷入循环。利用快慢指针算法解决此判环问题,无需额外哈希表空间。通过分析数学性质证明数字不会无限增大,确保算法终止。附带 C++ 代码实现与复杂度评估。

PgDevote发布于 2026/3/26更新于 2026/10/2599 浏览
LeetCode 202 快乐数:快慢指针解法详解

快乐数的定义

快乐数(Happy Number)是一个有趣的数学概念。对于一个正整数,如果将其各位数字的平方和不断进行替换,最终能够得到 1,那么这个数就被称为快乐数。反之,如果陷入一个不包含 1 的循环,那么这个数就是不快乐的。

以 19 为例:

19 → 1² + 9² = 82
82 → 8² + 2² = 68
68 → 6² + 8² = 100
100 → 1² + 0² + 0² = 1

经过 4 步变换,19 到达了终点 1,因此它是快乐数。

解题思路:链表思维转换

虽然处理的是数字,但我们可以把每个数字看作链表中的一个节点,变换规则看作指向下一个节点的指针。这样,快乐数问题就转化为了经典的链表判环问题。

如果不快乐,数字序列会进入循环;如果快乐,序列最终指向 1 并结束。

快慢指针策略

在链表判环中,快慢指针(Floyd's Cycle Detection)是高效且节省空间的方案。

  • 慢指针(slow):每次走一步(一次变换)。
  • 快指针(fast):每次走两步(两次变换)。

如果存在环,快慢指针终将相遇;如果数字快乐,快指针会率先到达 1。

算法实现:C++ 代码解析

核心逻辑

我们需要两个函数:一个是计算数字变换的辅助函数,另一个是主判断逻辑。

// 计算数字 n 的下一个变换结果
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 = ((fast)); 
    }
     fast == ; 
}
getNext
getNext
// 快指针走两步
return
1
// 判断快指针是否到达 1

这里有个细节要注意:快指针初始位置设为 getNext(n),是为了让它在第一次循环前就已经领先一步,避免初始状态 slow == fast 直接退出循环。

数学深度:数字会无限增大吗?

一个自然的疑问是:在变换过程中,数字会不会变得越来越大,最终无限增长?

对于一个 m 位数 n,其各位数字平方和的最大值为 81m(当所有位都是 9 时)。

  • 当 m=3 时,最大和为 243(3×81),远小于 999。
  • 当 m=4 时,最大和为 324,远小于 9999。

事实上,对于任何大于 3 位的数字,经过一次变换后数字都会变小。因此,数字不会无限增大,最终要么收敛到 1,要么进入一个有限的循环。这保证了算法必然终止。

复杂度分析与优化

  • 时间复杂度:O(log n)。因为每次变换都会显著减少数字的大小(对于大数而言),且循环次数有限。
  • 空间复杂度:O(1)。我们只使用了常数个额外变量,没有使用哈希表存储历史路径。

扩展思考

  1. 快乐数的密度:随着数字增大,快乐数的比例会如何变化?
  2. 快乐素数:既是素数又是快乐数的数字,如 7、13、19 等。
  3. 连续快乐数:是否存在连续的快乐数?(例如 31 和 32 都是快乐数)

快乐数问题不仅是一个有趣的编程练习,更是数学之美的一个缩影。它展示了如何将看似简单的数字变换转化为深刻的算法问题,并通过巧妙的思维转换找到高效的解决方案。

目录

  1. 快乐数的定义
  2. 解题思路:链表思维转换
  3. 快慢指针策略
  4. 算法实现:C++ 代码解析
  5. 核心逻辑
  6. 数学深度:数字会无限增大吗?
  7. 复杂度分析与优化
  8. 扩展思考

更多推荐文章

查看全部
  • JavaScript 性能优化实战指南
  • OpenClaw 在 Linux/Ubuntu 上的安装与部署实战
  • 知网 AIGC 检测升级下的论文降重与去 AI 痕迹指南
  • AI Agent 开发入门:零基础学习指南
  • 常见排序算法详解与 Java 实现
  • Unidbg 环境下解决 Native 调用 Java 方法报错问题
  • 飞算 JavaAI 智能编程助手功能介绍
  • AI 大模型全面概述
  • CES 2025 硬件竞争与大模型技术前沿综述
  • Llama-Factory 实现模型蒸馏:Teacher-Student 架构探索
  • Java 反射与方法句柄:动态编程深度解析
  • VSCode Copilot 配置文件提示未知工具警告
  • SBUS 协议详解:从原理到 STM32 实战
  • Meta-Llama-3-8B-Instruct 代码能力测试及 HumanEval 45+ 解析
  • 递归与回溯算法实战:汉诺塔、链表操作及快速幂
  • Python 异步编程实战:构建高性能网络应用
  • 基于大模型与知识库的 Code Review 实践
  • 多模态模型入门进阶:MiniGPT-4、Qwen-VL、InternVL 与 DeepSeek-VL 详解
  • Code Llama 7B 快速上手指南
  • AI 产品经理入门指南:核心技能与常见误区解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online