[C++算法]快乐数

题目描述:

题目来源:力扣「快乐数」

题目描述:

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

**「快乐数」**定义为:

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

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

示例 1: 输入 n = 19,返回 true。计算过程如下:

  • 1² + 9² = 82
  • 8² + 2² = 68
  • 6² + 8² = 100
  • 1² + 0² + 0² = 1

最终结果为 1,因此 19 是快乐数。

示例 2: 输入 n = 2,返回 false。计算过程如下:

  • 2² = 4
  • 4² = 16
  • 1² + 6² = 37
  • 3² + 7² = 58
  • 5² + 8² = 89
  • 8² + 9² = 145
  • 1² + 4² + 5² = 42
  • 4² + 2² = 20
  • 2² + 0² = 4

可以看到,数值进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环,始终无法变为 1,因此 2 不是快乐数。

边界情况: 当 n = 1 时,1² = 1,直接满足条件,无需任何迭代即可返回 true。

算法原理:

类比判断链表是否有环

解法:快慢双指针

1.定义快慢双指针

2.慢指针每次移动一步快指针每次移动两步

3.判断相遇的数的值即可。值为1则为快乐数

双指针仅仅是一个思想,我们可以用数组的下标充当指针,某一个数充当一个指针。

cpp 复制代码
class Solution 
{
   int clsum(int  n)//返回n这个数的每一位的平方和
   {
        int sum =0;
        while(n)
        {        
            int t =n%10; //
            sum+=t*t;
            n/=10;
        }
        return sum;
   }
public:
    bool isHappy(int n) 
    {
        int slow =n;
        int fast =clsum(n);
        while(slow!=fast)
        {
            slow=clsum(slow); //slow走一步
            fast =clsum(clsum(fast));//fast走两步
        }
        return fast==1;
    }
};

复杂度分析:

该快慢双指针解法的时间复杂度为 O(log n),空间复杂度为 O(1)。

为什么时间复杂度是 O(log n) 而不是 O(n)?关键在于 clsum 函数对每个数求各位数字平方和的过程。对于一个 k 位数,clsum 需要执行 k 次循环,而 k = log10(n),因此单次计算平方和的代价是 O(log n)。

更重要的是,快乐数序列中的数值会迅速缩小。以最大的 10 位数 9999999999 为例,其各位平方和为 9² × 10 = 810,也就是说,无论初始的 n 有多大,经过一次 clsum 之后,数值都会立刻降到 810 以下。此后所有参与计算的数都落在 [1, 810] 这个有限区间内,快慢指针最多在这个区间内循环若干次就会相遇,循环次数是一个与 n 的位数无关的常数。

因此,总时间复杂度 = 常数次循环 × 每次 O(log n) 的平方和计算 = O(log n)。如果误以为是 O(n),通常是忽略了「平方和运算会迅速压缩数值范围」这一关键性质,误把循环次数当成了与 n 成正比。

相关推荐
zyl7651 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖5 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌5 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F5 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_307779135 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins5 小时前
c++新增頭文件
c++
Shadow(⊙o⊙)6 小时前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
tomwang03226 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!6 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
by209996 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表