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

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

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

PgDevote发布于 2026/3/26更新于 2026/9/867 浏览
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 = getNext(getNext(fast)); // 快指针走两步
    }
    return fast == 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. 扩展思考

更多推荐文章

查看全部
  • JiaJiaOCR:纯 Java 实现的 OCR 解决方案
  • JDK 17 安装与环境配置实战指南
  • Kafka 核心机制与架构深度解析
  • HDFS 核心组件深度解析:分布式文件系统架构
  • 分布式架构与微服务中的 Session 同步方案
  • TRAE 与 VSCode 中的 Git 版本管理实战
  • 2026 年国家自然科学基金 AI 使用声明撰写位置与规范
  • CMake 项目中 Vcpkg、Conan 与 Spack 的 C++ 依赖管理对比
  • 黑客的四个级别与自学路线中的常见误区
  • 计算机基础知识总结:操作系统、网络、数据库与 C++
  • 前端面试复盘:从八股文到场景题的转变与应对策略
  • 基于 aivectormemory 实现 AI 长期记忆方案
  • 基于 SpringBoot 的个性化礼品电商平台设计与实现
  • 前端通用 AI Rules 定义,适用于 Cursor 等主流 AI 开发工具
  • Nginx 1.29.6 发布:新增上游粘性会话支持,性能与稳定性全面提升
  • 基于 Python 的旅游大数据分析与推荐系统实战
  • 使用 TRAE CN 与 MCP 协议将 MasterGo 设计稿转为前端代码
  • Meta Llama 3.1 70B 与 Mistral Large 2 128B 深度对比
  • 命令行工具 MCPHost:利用模型上下文协议连接大模型与外部工具
  • 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