【LeetCode面试150】——202快乐数

博客昵称:沈小农学编程

作者简介:一名在读硕士,定期更新相关算法面试题,欢迎关注小弟!

PS:哈喽!各位CSDN的uu们,我是你的小弟沈小农,希望我的文章能帮助到你。欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘

题目难度:简单

默认优化目标:最小化时间复杂度。

Python默认为Python3。

1 题目描述

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

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。

  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

  • 如果这个过程 结果为 1,那么这个数就是快乐数。

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

示例 1:

复制代码
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

复制代码
输入:n = 2
输出:false

提示:

  • 1 <= n <= 231 - 1

2 题目分析

输入是一个整数n,输出是布尔值。约束条件是,如果是快乐数,返回true;反之,返回false。

根据快乐数的定义,我们猜测有以下三种可能:

  1. 最终到1
  1. 最终会进入循环

  2. 值会越来越大,最后到无穷大

到1的情况如下图所示:

循环的情况如下图所示:

现在我们来分析第三种情况。

我们对不同位数的数取最大值,看看它们的下一个数和它们自身相比的是变大还是变小了。

位数 最大 下一个数
1 9 81
2 99 162
3 999 243
4 9999 324
13 9999999999999 1053

对于三位数字,他不可能大于243;而在4位以及4位以上的数字,最终也会跌落到3位数。所以,在最坏情况下,算法会在243以下的数字上循环,要么继续循环,要么到1。所以不会出现第三种情况。

3 代码实现

3.1 哈希表

我们使用哈希表记录已经出现过的快乐数,用于检查某个数是否在循环链当中。

时间复杂度O(log n),空间复杂度O(log n)。当n足够大时,这和n的位数有关,即log n。

C++代码实现

cpp 复制代码
class Solution {
public:
    bool isHappy(int n) {
        auto getNext = [](int n) {
            int sum = 0;
            while (n > 0) {
                int digit = n % 10;
                n /= 10;
                sum += digit * digit;
            }
            return sum;
        };
​
        std::unordered_set<int> seen;
        while (n != 1 && seen.find(n) == seen.end()) {
            seen.insert(n);
            n = getNext(n);
        }
​
        return n == 1;
    }
};
复制代码

Python代码实现

python 复制代码
class Solution:
    def isHappy(self, n: int) -> bool:
        def nexthappy(n):
            sum=0
            while n>0:
                n,d=divmod(n,10)
                sum+=d**2
            return sum
        seen=set()
        while n!=1 and n not in seen:
            seen.add(n)
            n=nexthappy(n)
​
        return n==1

3.2 快慢指针法

我们使用两个指针,一个叫"兔子",一个叫"乌龟"。"兔子"一次前进两格,"乌龟"一次一格。如果n是一个快乐数,即没有循环,那么快跑者会比慢跑者先到达数字1;反之,会在同一个数上相遇。

时间复杂度O(log n),空间复杂度O(1)。

C++代码实现

cpp 复制代码
class Solution {
public:
    bool isHappy(int n) {
        auto getNext = [](int n) {
            int sum = 0;
            while (n > 0) {
                int digit = n % 10;
                n /= 10;
                sum += digit * digit;
            }
            return sum;
        };
​
        int slow = n;
        int fast = getNext(n);
        while (fast != 1 && slow != fast) {
            slow = getNext(slow);
            fast = getNext(getNext(fast));
        }
​
        return fast == 1;
    }
};

Python代码实现

python 复制代码
class Solution:
    def isHappy(self, n: int) -> bool:
        def nexthappy(n):
            sum=0
            while n>0:
                n,d=divmod(n,10)
                sum+=d**2
            return sum
​
        slow=n
        fast=nexthappy(n)
        while fast!=1 and slow!=fast:
            slow=nexthappy(slow)
            fast=nexthappy(nexthappy(fast))
        return fast==1

参考文献

力扣面试经典150题

力扣官方题解

相关推荐
Kaltistss1 分钟前
98.验证二叉搜索树
算法·leetcode·职场和发展
im_AMBER2 分钟前
学习日志05 python
python·学习
知己如祭5 分钟前
图论基础(DFS、BFS、拓扑排序)
算法
大虫小呓7 分钟前
Python 处理 Excel 数据 pandas 和 openpyxl 哪家强?
python·pandas
mit6.82414 分钟前
[Cyclone] 哈希算法 | SIMD优化哈希计算 | 大数运算 (Int类)
算法·哈希算法
c++bug17 分钟前
动态规划VS记忆化搜索(2)
算法·动态规划
哪 吒19 分钟前
2025B卷 - 华为OD机试七日集训第5期 - 按算法分类,由易到难,循序渐进,玩转OD(Python/JS/C/C++)
python·算法·华为od·华为od机试·2025b卷
小刘同学3211 小时前
C++11 特性
c++·c11新特性
军训猫猫头1 小时前
1.如何对多个控件进行高效的绑定 C#例子 WPF例子
开发语言·算法·c#·.net