学习笔记--算法(双指针)3

快乐数

. - 力扣(LeetCode)


题目

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

「快乐数」 定义为:

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

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

示例 1:

输入:n = 19

输出:true

解释:

1^2 + 9^2 = 82

8^2 + 2^2 = 68

6^2 + 8^2 = 100

1^2 + 0^2 + 0^2 = 1

示例 2:

输入:n = 2

输出:false

解释:

(这⾥省去计算过程,只列出转换后的数)

2 -> 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16

往后就不必再计算了,因为出现了重复的数字,最后结果肯定不会是 1

提示:

1 <= n <= (2^31 )- 1


图解

最终结果:重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

那么可以总结出以下的规律:

那么如何将快慢指针这一概念应用到这道题中呢?

由于没有所谓的指针,那就把某一个数当成一个指针。比如下图:

由于 ,所以要让 ,也就是让slow指向第一个数,fast指向第三个数,这样才能进入循环。

简单证明一下为什么不会出现没有循环的情况:

a. 经过⼀次变化之后的最⼤值 9^2 * 10 = 810 ( 2^31-1=2147483647 。选⼀个更⼤的最

⼤ 9999999999 ),也就是变化的区间在 [1, 810] 之间;

b. 根据「鸽巢原理」,⼀个数(从1~2^31-1)变化 811 次(最糟糕的情况是变化了810次,没有一次是重复的,但在第811次必定会重复)之后,必然会形成⼀个循环;

c. 因此,变化的过程最终会⾛到⼀个圈⾥⾯,因此可以⽤「快慢指针」来解决。


总结

为了⽅便叙述,将「对于⼀个正整数,每⼀次将该数替换为它每个位置上的数字的平⽅和」这⼀个操作记为 x 操作;题⽬告诉我们,当我们不断重复 x 操作的时候,计算⼀定会「死循环」,死的⽅式有两种:

▪ 情况⼀:⼀直在 1 中死循环,即 1 -> 1 -> 1 -> 1......

▪ 情况⼆:在历史的数据中死循环,但始终变不到 1

由于上述两种情况只会出现⼀种,因此,只要我们能确定循环是在「情况⼀」中进⾏,还是在「情况⼆」中进⾏,就能得到结果。根据上述的题⽬分析,我们可以知道,当重复执⾏ x 的时候,数据会陷⼊到⼀个「循环」之中。

⽽「快慢指针」有⼀个特性,就是在⼀个圆圈中,快指针总是会追上慢指针的,也就是说他们总会相遇在⼀个位置上。如果相遇位置的值是 1 ,那么这个数⼀定是快乐数;如果相遇位置不是 1的话,那么就不是快乐数。


如何求一个数 n 每个位置上的数字的平方和。

a. 把数 n 每⼀位的数提取出来:

循环迭代下⾯步骤:

i. int t = n % 10 提取个位;

ii. n /= 10 ⼲掉个位;

直到 n 的值变为 0 ;

b. 提取每⼀位的时候,⽤⼀个变量 tmp 记录这⼀位的平⽅与之前提取位数的平⽅和

tmp = tmp + t * t


代码

复制代码
public int squaresSum(int n){
    int sum = 0;
    while(n != 0){
        int a = n % 10;
        sum += a * a;
        n /= 10;
    }
    return sum;
}

public boolean isHappy(int n) {
    //slow指向第一个数,fast指向第三个数
    int slow = n;
    int fast = squaresSum(n);
    while(slow != fast){
        //slow向后移动一步,fast向后移动两步
        slow = squaresSum(slow);
        fast = squaresSum(squaresSum(fast));
    }
    //快慢指针中的一个指针为1,就说明是快乐数
    return slow == 1;
}
相关推荐
野老杂谈10 小时前
如何快速学习智能合约开发语言 Solidity
开发语言·学习·智能合约·solidity·以太坊·区块链开发
kida_yuan10 小时前
【从零开始】17. 中文摘要提取工具
python·算法·数据分析
Han.miracle10 小时前
Java线程的学习—多线程(一)
java·开发语言·学习
是店小二呀10 小时前
Trilium非线性笔记测评:本地知识库+远程协作,构建你的第二大脑!
笔记
忧郁奔向冷的天10 小时前
视觉SLAM十四讲2nd—学习笔记(二)20250817
笔记·学习
未到结局,焉知生死11 小时前
PAT每日三题
算法
进击的炸酱面11 小时前
第三章 线性模型
人工智能·算法·机器学习
立志成为大牛的小牛11 小时前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
摇滚侠12 小时前
Spring Boot3零基础教程,Actuator 导入,笔记82
java·spring boot·笔记
CoovallyAIHub12 小时前
一致性模型:单步生成高质量图像,破解扩散模型速度瓶颈
深度学习·算法·计算机视觉