LeetCode例题讲解:快乐数

发布于:2024-05-10 ⋅ 阅读:(29) ⋅ 点赞:(0)

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

「快乐数」 定义为:

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

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

示例 1:

输入:n = 19
输出:true
解释:

首先需要将给出的数值进行拆分:
 

bool isHappy(int n) {
    int r = 0;
    n = 15646;
    while(n != 0)
    {
        int d= n  % 10;
        n /= 10;  
        //r += d * d;
        printf("%d\n",d);
    }
   // printf("%d\n",r);
    return false;
} 

之后开始按照题目对其计算平方和,将代码封装起来

int next_n(int n)
{
    int r = 0;
    while(n != 0)
    {
        int d= n % 10;
        n /= 10;  
        r += d * d;
        printf("%d\n",d);
    }
        return r;
}
bool isHappy(int n) 
{

      n = next_n(n);  
      printf("%d\n",n);
        
    return true;
} 

之后加上条件判断,当该数之前出现过时,则退出循环,未出现过则继续

int next_n(int n)
{
    int r = 0;
    while(n != 0)
    {
        int d= n % 10;
        n /= 10;  
        r += d * d;
    }
        return r;
}
bool contains(int *history, int size , int n)
{
    for(int i = 0; i < size ; i++ )
    {
        if(history[i] ==n )
        return true;
    }
    return false;

}
bool isHappy(int n) 
{
    int history[10000];
    int size = 0;
    while(!contains(history, size , n))
    {
        history[size] = n;
        size++;
        n = next_n(n);
    }  
    return n == 1;
} 

中间添加了一个条件判断,需要判断该数在之前有没有出现过。

实际上history最大只有9*9*10次,即810;

之后简化算法,利用龟兔赛跑,寻找重复数

int next_n(int n)
{
    int r = 0;
    while(n != 0)
    {
        int d= n % 10;
        n /= 10;  
        r += d * d;
    }
        return r;
}

bool isHappy(int n) 
{
    int slow = n;
    int fast = n;
    do
    {
        slow = next_n(slow);
        fast = next_n(fast);
        fast = next_n(fast);
    } while(slow != fast);
    return fast == 1;
}