返回

分享LeetCode每日一题:快乐数(No.202)的解题报告

见解分享

题目

给你一个非负整数 n ,请你判断该整数是否是快乐数。
如果一个整数的数字平方和为一个位数,则认为它是快乐数,否则,它不是快乐数。
计算过程从初始数字 n 开始,依次循环以每个数字的平方和作为下一次迭代的输入,直到出现循环或出现一个位数。
如果出现循环(即,某些数字组合不断重复出现),则初始数字不是快乐数;
如果出现一个位数(即,数字不再改变),则初始数字是快乐数。

示例

示例 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^2 = 4
4^2 = 16
1^6 = 37
3^2 + 7^2 = 58
5^2 + 8^2 = 89
8^2 + 9^2 = 145
1^4 + 4^2 + 5^2 = 42
4^2 + 2^2 = 20
2^2 + 0^2 = 4

思考

我们首先来思考一下,什么是快乐数的定义。快乐数是一个能够最终达到1的数字,而不会陷入无限循环。

比如,19是一个快乐数,因为我们可以通过以下步骤得到1:

1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

而2不是一个快乐数,因为我们可以通过以下步骤得到一个无限循环:

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

实现

既然我们已经理解了快乐数的定义,我们就可以开始实现一个算法来判断一个数字是否是快乐数。

我们可以使用一个哈希表来记录我们已经遍历过的数字。每当我们遇到一个新的数字时,我们就将其添加到哈希表中。如果我们遇到一个已经存在于哈希表中的数字,那么我们就说明已经陷入了一个无限循环,这个数字不是一个快乐数。

以下是这个算法的伪代码:

def is_happy(n):
  # 创建一个哈希表来记录已经遍历过的数字
  seen = set()

  # 循环,直到找到1或者陷入无限循环
  while n not in seen:
    # 将n添加到哈希表中
    seen.add(n)

    # 计算n的数字平方和
    n = sum(int(i) ** 2 for i in str(n))

  # 如果n为1,则返回True
  # 如果n在哈希表中,则返回False
  return n == 1

复杂度

该算法的时间复杂度为O(n),其中n为输入数字的长度。这是因为我们在哈希表中查找和添加元素的时间复杂度都是O(1)。

快乐数背后的数学思想

快乐数背后的数学思想非常有趣。它表明,如果一个数字的数字平方和是一个位数,那么这个数字要么是1,要么是陷入了一个无限循环。

我们可以用以下数学公式来证明这一点:

n = a_1^2 + a_2^2 + ... + a_k^2

其中,a_1, a_2, ..., a_k是n的数字。

我们知道,每个a_i都是一个非负整数。因此,a_i^2也是一个非负整数。

因此,n的数字平方和也是一个非负整数。

如果n的数字平方和是一个位数,那么n的数字平方和要么是1,要么是大于1。

如果n的数字平方和是1,那么n就是一个快乐数。

如果n的数字平方和大于1,那么n的数字平方和的数字平方和也会是一个非负整数。

因此,n的数字平方和的数字平方和也会要么是1,要么是大于1。

以此类推,我们可以得出结论:如果一个数字的数字平方和是一个位数,那么这个数字要么是1,要么是陷入了一个无限循环。

快乐数的一些变形题

快乐数有一些变形题,它们也很好玩。比如,我们可以问:

  • 一个数字的数字平方和的数字平方和的数字平方和...的数字平方和是不是最终也会变成1?
  • 快乐数的个数有多少?
  • 快乐数的分布情况是怎样的?

这些问题都是很有趣的,您可以尝试自己解答它们。