Java算法精讲:双指针(三)

📚 目录

  • [1. 题目解析](#1. 题目解析)

  • [2. 算法原理](#2. 算法原理)

  • [3. 编写代码](#3. 编写代码)

  今天我们来做LeetCode上的经典题目---202. 快乐数

1. 题目解析

  解决这道题,常见有两种思路:

  1. 哈希集合判重:用HashSet记录迭代过程中出现的数字,出现重复就说明有环。优点是逻辑直观,缺点是需要额外的O(log n)空间。
  2. 快慢指针判环:利用快慢指针相遇来判断环的存在,空间复杂度O(1),也是我们双指针专题的核心考点。
      此时,我们今天解这道题用的是:双指针->快慢指针.
      

[🔙 返回目录](#🔙 返回目录)


2. 算法原理

  此时我们还遇到了一种特殊情况:这个数字呈现直线 的情况;

  这里我们要明确一点:本题中,数字的迭代路径不可能一直呈直线,所有数最终都会进入循环。

  原因有两点:

  1. 鸽巢原理的限制 :无论初始数字多大 ,每次求各位平方和时,数字都会快速缩小,最终落入 一个有限的数字集合 中。根据鸽巢原理 ,迭代次数超过集合大小后,必然会出现重复数字,从而进入循环。
  2. 快乐数的收敛特性:如果数字是快乐数,它最终会变成1,而1的平方和永远是1,会形成一个值全为1的自循环,而非一直延伸的直线。

  因此,我们只需要判断迭代路径是否进入循环,并且判断循环中是否包含1,就能得出结果。

额外拓展:鸽巢原理:

  我们可以结合题目给定的输入范围 1 ≤ n < 2^31 - 1 ,来量化这个有限集合的大小:

  2^31-1 是一个10位数 ,其各位全为9时的平方和最大 ,为 10×9²=810 。后续迭代中数字会持续缩小,因此所有迭代值都落在 [1, 810] 这个有限集合中。根据鸽巢原理,迭代次数超过 810次后,必然会出现重复数字 ,进入循环 。

  此时,我们特殊情况就不会存在!!!
[🔙 返回目录](#🔙 返回目录)


3. 编写代码

java 复制代码
class Solution {
    //求每一位数字的平方和
    public int sumbit(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;
        //先让快指针先走1步
        int fast = sumbit(n);
        while(slow!=fast) {
            //慢指针走一步
            slow = sumbit(slow);
            //快指针走两步
            fast = sumbit(sumbit(fast));
        }
        //或者是fast
        return slow==1;
    }
}

  复杂度分析:

  • 时间复杂度 :O(log n)。每次迭代中,数字的大小都会快速缩小,且快慢指针相遇的时间与循环的长度成正比,整体复杂度和数字的位数相关。
  • 空间复杂度 :O(1)。快慢指针只使用了常数级别的额外空间 ,这也是快慢指针解法相比哈希集合解法的优势。
      两种解法对比:
解法 时间复杂度 空间复杂度 特点
哈希集合判重 O(log n) O(log n) 逻辑直观,容易理解
快慢指针判环 O(log n) O(1) 空间复杂度最优,是双指针的经典应用

  总结 :

  这道题的核心考点,是将**"数字迭代"问题转化为"链表判环"问题**,并用快慢指针解决。鸽巢原理则 证明了循环必然存在 ,为我们的解法提供了理论支撑。掌握这个思路,以后遇到类似的循环问题,都可以用快慢指针来解决。
[🔙 返回目录](#🔙 返回目录)


相关推荐
weixin_307779133 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
一水鉴天6 小时前
映射、哈希表与哈斯图:计算机科学的三种基线 20261003(元宝)
开发语言·人工智能
Frank_refuel7 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
Wang's Blog7 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071578 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
hetao17338379 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
\光辉岁月/9 小时前
5.java-数组
java·开发语言
Java后端的Ai之路9 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang9 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
Zootopia6269 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信