【双指针】专题:LeetCode 202题解——快乐数

快乐数

一、题目链接

快乐数

二、题目

三、题目解析

快乐数的定义中第二点最重要,只有两种情况,分别拿示例1、示例2分析吧:

示例1中一旦出现1了,继续重复过程就还是1,所以一旦出现1了就返回true。

示例2中会出现无限循环,始终变不到1。

四、算法原理

在快乐数的定义里,最终结果要么是1,要么是无限循环但始终变不到1。也就是类似示例1、示例2的情况。

将上述两种情况抽象成图:

能抽象成一种图的原因:情况1是出现1了,继续重复过程一直是1,也就是也有一个环,只不过环里的数都是1罢了。而情况2中环里的数都不是1。

抽象成带环的图很像之前学习过的"判断链表是否带环"一题,只不过本题不是判断是否有环,而是判断环里的每一个值是多少。"判断链表是否带环"一题用的是"快慢双指针法",本题同理也用这个方法。

步骤:

  1. 定义快慢双指针
  2. 慢指针每次向后走1步,快指针每次向后走2步
  3. 判断快慢指针相遇时的值

双指针法只是一种思想,并不是用真的指针,像本题中,甚至可以把某一个数充当成指针。

扩展

若题中没给定义第二点呢,是不是还有第3种情况:一个数一直进行下去永不成环。

证明:一个数进行下去一定会成环。

运用到了鸽巢原理(抽屉原理):n个巢穴,n + 1只鸽子,至少有一个巢穴里的鸽子数是大于1的。

五、编写代码

因为经常用到这个数上每一位的平方和,所以可以封装成一个函数完成:

cpp 复制代码
// 返回 n 这个数每一位的平方和
int bitSum(int n)
{
	int sum = 0;
	while (n)
	{
		int t = n % 10;
		sum += t * t;
		n /= 10;
	}
	return sum;
}

一上来定义slow和fast相等会导致循环进不去,所以应该把slow和fast定义成不相等的:

cpp 复制代码
// 定义快慢双指针
int slow = n, fast = n;
// 慢指针每次向后走1步,快指针每次向后走2步
while (slow != fast)
	{}

可以让fast指向第二个位置。相当于一上来就让slow走1步到第一个数的位置,fast走2步到第二个数的位置:

cpp 复制代码
// 定义快慢双指针
int slow = n, fast = bitSum(n);
// 慢指针每次向后走1步,快指针每次向后走2步
while (slow != fast)
	{}

完整代码如下:

cpp 复制代码
class Solution {
public:
    // 返回 n 这个数每一位的平方和
    int bitSum(int n)
    {
        int sum = 0;
        while (n)
        {
            int t = n % 10;
            sum += t * t;
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) 
    {
        // 定义快慢双指针
        int slow = n, fast = bitSum(n);
        // 慢指针每次向后走1步,快指针每次向后走2步
        while (slow != fast)
        {
            slow = bitSum(slow);
            fast = bitSum(bitSum(fast));
        }
        // 判断快慢指针相遇时的值
        return slow == 1;
    }
};
相关推荐
拼好饭和她皆失1 小时前
dfs 第一次加训 详解 下
算法·深度优先
梁下轻语的秋缘3 小时前
每日c/c++题 备战蓝桥杯(P2241 统计方形(数据加强版))
c语言·c++·蓝桥杯
笑鸿的学习笔记4 小时前
虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系
笔记·ue5·虚幻
学习编程的gas5 小时前
C++面向对象编程入门:从类与对象说起(一)
开发语言·c++
冼紫菜5 小时前
【Spring Boot 多模块项目】@MapperScan失效、MapperScannerConfigurer 报错终极解决方案
java·开发语言·mybatis
Bear on Toilet5 小时前
Bug日记——实现“日期类”
开发语言·c++·bug
apcipot_rain5 小时前
《面向对象程序设计-C++》实验五 虚函数的使用及抽象类
开发语言·c++
半新半旧7 小时前
mongodb 学习笔记
笔记·学习·mongodb
明月看潮生8 小时前
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型
开发语言·青少年编程·rust·编程与数学