学习笔记--算法(双指针)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;
}
相关推荐
luckys.one1 分钟前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
~|Bernard|2 小时前
在 PyCharm 里怎么“点鼠标”完成指令同样的运行操作
算法·conda
战术摸鱼大师2 小时前
电机控制(四)-级联PID控制器与参数整定(MATLAB&Simulink)
算法·matlab·运动控制·电机控制
Christo32 小时前
TFS-2018《On the convergence of the sparse possibilistic c-means algorithm》
人工智能·算法·机器学习·数据挖掘
汇能感知2 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun2 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
好家伙VCC3 小时前
数学建模模型 全网最全 数学建模常见算法汇总 含代码分析讲解
大数据·嵌入式硬件·算法·数学建模
茯苓gao3 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾3 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT4 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习