学习笔记--算法(双指针)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;
}
相关推荐
卷福同学1 天前
不用服务器,不用配环境,我10分钟上线了一个AI Agent
人工智能·后端·算法
问君能有几多愁~1 天前
C++ 数据结构复习笔记
数据结构·c++·笔记
至乐活着1 天前
深入解析跳表SkipList:原理、实现与性能优化实战
数据结构·算法·跳表·skiplist·java实现
r_oo_ki_e_1 天前
Java Map 集合学习笔记
java·笔记·学习
Jerry1 天前
LeetCode 383. 赎金信
算法
ai产品老杨1 天前
H264 H265视频分析常见问题和排查清单
人工智能·算法·音视频
Jerry1 天前
LeetCode 454. 四数相加 II
算法
笨鸟先飞的橘猫1 天前
skynet——sharetable学习
学习·skynet
liuyicenysabel1 天前
大模型学习笔记 · 第八篇 · 进阶:偏好对齐与多卡训练
人工智能·笔记·学习
可编程芯片开发1 天前
基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真
算法