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

算法:快慢指针判断快乐数

快乐数判定涉及数字变换序列的循环检测。通过计算各位数字平方和,若最终收敛至 1 则为快乐数,否则陷入死循环。利用快慢指针可在线性时间内检测环路,无需额外哈希表存储历史状态。Java 实现需关注位运算效率及整数范围。

竹影清风发布于 2026/3/23更新于 2026/10/979 浏览
算法:快慢指针判断快乐数

文章配图

文章配图

题目描述

编写一个算法来判断一个正整数 n 是不是快乐数。

**「快乐数」**的定义如下:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。
  • 如果这个过程结果为 1,那么这个数就是快乐数。

如果 n 是快乐数就返回 true;不是,则返回 false。

示例 1: 输入:n = 19 输出:true 解释: 1² + 9² = 82 8² + 2² = 68 6² + 8² = 100 1² + 0² + 0² = 1

示例 2: 输入:n = 2 输出:false

提示: 1 <= n <= 2³¹ - 1

思路分析

这道题的核心在于检测序列中是否存在环。如果我们不断计算各位数字的平方和,得到的新数列要么最终收敛到 1(快乐数),要么进入一个不包含 1 的循环(非快乐数)。

既然存在'循环'的可能性,我们自然联想到链表中的环检测问题。这里不需要显式地构建链表,而是将数值变换看作节点间的跳转关系。

快慢指针(Floyd 判圈算法) 是解决此类问题的经典方案:

  1. 慢指针每次走一步:计算一次平方和。
  2. 快指针每次走两步:连续计算两次平方和。
  3. 如果存在环,快指针最终一定会追上慢指针。
  4. 当两者相遇时,检查当前值是否为 1。如果是,说明进入了以 1 为终点的循环(即 1->1);如果不是,说明陷入了死循环。

这种方法的优势在于空间复杂度仅为 O(1),无需使用哈希表记录历史访问过的数字,非常适合处理大范围的整数输入。

代码实现

下面是 Java 语言的完整实现。为了保持逻辑清晰,我将计算平方和的逻辑封装成了一个辅助方法。

public class Solution {
    // 计算各位数字的平方和
    private int bitSum(int n) {
        int sum = 0;
        while (n != 0) {
            int tmp = n % 10;
            sum += tmp * tmp;
            n /= 10;
        }
        return sum;
    }

    public boolean isHappy(int n) {
        int slow = n;
        int fast = bitSum(n);
        
        // 快慢指针移动,直到相遇
        while (slow != fast) {
            slow = bitSum(slow);
            fast = bitSum(bitSum(fast));
        }
        
        // 相遇点如果是 1,则是快乐数
        return fast == 1;
    }
}

关键点说明:

  • 初始化差异:注意 fast 初始化为 bitSum(n) 而不是 n。这是为了确保在第一次循环前,快指针已经领先一步,避免在 n=1 的特殊情况下直接跳过循环判断(虽然逻辑上 slow==fast 也能处理,但分开初始化更符合 Floyd 算法的常规直觉)。
  • 边界情况:当 n=1 时,slow=1, fast=1,循环不执行,直接返回 true,符合定义。
  • 性能:由于数字平方和增长有限,对于任意正整数,其变换后的值很快就会落入一个较小的范围内,因此循环次数不会太多,时间复杂度可视为 O(log n) 级别。

文章配图

文章配图

目录

  1. 题目描述
  2. 思路分析
  3. 代码实现

更多推荐文章

查看全部
  • 前端 HTML 转 PDF 的两种主流方案深度解析
  • Flutter for OpenHarmony:使用 money2 实现高精度金融计算
  • DeepSeek、Kimi、笔灵等 5 款网文 AI 写作工具实测横评
  • WebGL 矩阵变换实战:平移旋转缩放与复合动画
  • OpenClaw 腾讯云服务器部署与飞书对接实战指南
  • Python 基础语法详解
  • Spring Boot 拦截器详解与实战
  • OpenCV 调整图像对比度与亮度的方法
  • Visual C++ 运行库缺失问题排查与修复指南
  • 鸿蒙 ArkWeb 混合开发:加载机制与 Cookie 管理
  • Z-Image-Turbo 云端 AI 绘画快速部署与使用指南
  • Web 安全实战:Robots.txt 协议原理与利用
  • Java 长字符串处理的 5 种实用技巧
  • 手写 C++ TCP 服务器:自定义协议与粘包处理实战
  • OpenClaw 对接飞书机器人高频踩坑与配置排查
  • Agent 的 Demo 时代结束了:2026 年真正的战争发生在 Runtime
  • 用 pthread 实现一个 C++ 线程池
  • 基于C#的OPC转Web API服务器框架源码,集成IoT与Modbus及PLC协议
  • 大模型本地部署与优化实战指南
  • OpenClaw 集成 QVeris 实现 AI 实时数据查询

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

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

  • Gemini 图片去水印

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