题目:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
Python3代码实现:
class Solution:
def isHappy(self, n: int) -> bool:
# 定义了一个空的集合record,用来记录在过程中遇到的所有中间结果
record = set()
# 使用一个while True循环,一旦函数中的 return 语句被执行,
# 无论是 True 还是 False,都会立即终止循环和函数的执行
while True:
# 调用get_sum方法计算n的每一个数字的平方和(将会生成一个新的整数)
n = self.get_sum(n)
# 如果得到新的n为1,返回True,表示n是一个快乐数
if n == 1:
return True
# 如果我们得到的新n已经在集合当中,说明陷入了一个死循环,该数字不是快乐数
if n in record:
return False
else:
# 否则将n加入集合当中,继续循环
record.add(n)
# 定义一个get_sum方法,计算给定整数 n 的每一位数字的平方和
def get_sum(self,n: int) -> int:
# 初始化new_num为0,,用来累加每一位数的平方和(例如19就是1和9的平方和)
new_num = 0
# 使用while n 遍历整数n的每一位数字
while n:
# 使用divmod函数将n分成商和余数(商是除以10的结果,余数是n的个位数)
n, r = divmod(n, 10)
# 计算余数的平方和,累加到new_num中,更新n为商,直到n为0,退出循环
new_num += r ** 2
# 返回new_num,这个就是n的每一位数字的平方和
return new_num
上述代码实现讲解:
上述代码实现了一个算法,用来判断一个给定的整数 n
是否是一个快乐数。快乐数是一个整数,当你对这个数执行一定的操作时,最终会得到 1,否则会陷入一个循环并永远不会到达 1。具体解释如下:
-
isHappy
方法:- 接受一个整数
n
作为输入。 - 定义一个空的集合
record
,用来记录在过程中遇到的所有中间结果(数字)。 - 使用
while True
循环:- 在循环的开始,调用
get_sum
方法来计算n
的每一位数字的平方和(这将生成一个新的整数)。 - 如果计算得到的新
n
等于 1,则返回True
,表示输入n
是一个快乐数。 - 如果新的
n
已经在record
集合中,说明已经进入了循环,所以返回False
,表示n
不是一个快乐数。 - 否则,将新的
n
加入到record
集合中,并继续循环。
- 在循环的开始,调用
- 接受一个整数
-
get_sum
方法:- 接受一个整数
n
作为输入。 - 初始化
new_num
为 0,用来累加每一位数字的平方。 - 使用
while n
循环来遍历整数n
的每一位数字:- 使用
divmod
函数将n
分成商和余数(商是除以 10 的结果,余数是n
的个位数)。 - 计算余数的平方,并将其累加到
new_num
中。 - 更新
n
为商,继续循环直到n
为 0。
- 使用
- 返回
new_num
,这就是n
的每一位数字的平方和。
- 接受一个整数
具体数字带入代码讲解:
使用数字 19
来测试这个代码:
-
isHappy
方法开始:record
集合初始化为空。- 输入数字
19
。
-
第一个循环迭代:
n = 19
,调用get_sum
方法计算19
的每一位数字的平方和。19
拆分为1
和9
。- 计算
1^2 + 9^2 = 1 + 81 = 82
。
- 得到
n = 82
。 82
不在record
集合中,所以将82
加入record
集合。record = {82}
。
-
第二个循环迭代:
n = 82
,调用get_sum
方法计算82
的每一位数字的平方和。82
拆分为8
和2
。- 计算
8^2 + 2^2 = 64 + 4 = 68
。
- 得到
n = 68
。 68
不在record
集合中,所以将68
加入record
集合。record = {68, 82}
。
-
第三个循环迭代:
n = 68
,调用get_sum
方法计算68
的每一位数字的平方和。68
拆分为6
和8
。- 计算
6^2 + 8^2 = 36 + 64 = 100
。
- 得到
n = 100
。 100
不在record
集合中,所以将100
加入record
集合。record = {68, 82, 100}
。
-
第四个循环迭代:
n = 100
,调用get_sum
方法计算100
的每一位数字的平方和。100
拆分为1
、0
和0
。- 计算
1^2 + 0^2 + 0^2 = 1 + 0 + 0 = 1
。
- 得到
n = 1
。 n = 1
,这是一个快乐数,isHappy
方法返回True
。
这样,我们已经通过一个具体数字 19
带入代码,解释了整个实现过程。最终结果为 True
,表示 19
是一个快乐数。
代码重难点讲解:
难点一:上述提到的调用 get_sum 方法计算 的每一位数字的平方和可能会存在疑问,我们以第二部的数字82为例来解释一下定义的这个方法:
-
方法定义:
get_sum
方法接受一个整数n
作为输入。- 初始化
new_num
为 0,用来累加每一位数字的平方和。
-
开始循环:
- 使用
while n:
循环,当n
不等于 0 时继续循环。- 首次进入循环时,
n = 82
。
- 首次进入循环时,
- 使用
-
计算每一位的平方和:
- 使用
divmod(n, 10)
将n
分成商和余数。divmod(82, 10)
返回(8, 2)
,商是8
,余数是2
。
- 计算
2
的平方并累加到new_num
上。2^2 = 4
。new_num = new_num + 4 = 0 + 4 = 4
。
- 更新
n
为商,继续循环。n = 8
。
- 使用
-
继续循环:
- 再次进入循环时,
n = 8
。 - 使用
divmod(n, 10)
将n
分成商和余数。divmod(8, 10)
返回(0, 8)
,商是0
,余数是8
。
- 计算
8
的平方并累加到new_num
上。8^2 = 64
。new_num = new_num + 64 = 4 + 64 = 68
。
- 更新
n
为商。n = 0
。
- 再次进入循环时,
-
循环结束:
n
已经变成0
,循环结束。- 返回
new_num
的值,即68
。
最终,get_sum
方法返回 68
,这是数字 82
的每一位数字的平方和。
难点二:
对于while True:这个代码的理解我觉得是一个难点,
在 Python 编程中,while True:
是一种无限循环的结构。这意味着循环将持续不断地执行,直到内部某些条件触发终止循环。
具体来说,在 while True:
循环内:
- 计算新的
n
:调用get_sum
方法来计算n
的每一位数字的平方和,并更新n
的值。 - 检查
n
是否为 1:如果n
等于 1,代码返回True
,表示输入数字是一个快乐数。这是一个返回语句,它将终止整个函数(包括while True
循环),并将True
作为结果返回给调用者。 - 检查
n
是否重复:如果n
已经在record
集合中,说明陷入了一个循环,代码返回False
,表示输入数字不是一个快乐数。同样,这是一个返回语句,它将终止整个函数,并将False
作为结果返回给调用者。 - 记录新的
n
:如果n
既不是 1 也不是重复的结果,则将新的n
加入record
集合中,继续循环。
因此,一旦 n
等于 1 或者 n
已经在 record
集合中出现过,代码将通过返回语句退出 while True
循环。不会再重新进入循环,整个函数的执行也会结束
不能理解的话:
简单来说就是:当循环内容中执行返回 True
或 False
时,while True
循环将终止,是因为 return
语句会立即停止当前函数的执行,并将返回值传递给调用者,一旦函数中的 return
语句被执行,无论是 True
还是 False
,都会立即终止循环和函数的执行。
综上,本文的对于力扣202. 快乐数的Python3解答,仅仅是个人学习资料记录,也十分高兴我的见解可以帮助其他的正在做这个题目的同学,基础较差,仅仅是个人见解,大神勿喷,欢迎交流,谢谢!