题目:编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
链接 https://leetcode.cn/problems/happy-number
memory = []
class Solution:
def isHappy(self, n: int) -> bool:
temp = 0
while n > 0:
temp = temp + (n % 10)**2
n = n // 10
if temp == 1:
return True
elif temp in memory:
return False
else:
memory.append(temp)
self.isHappy(temp)
自己测试的时候打印发现结果应该是对的,但却没有任何返回值
原因:该函数为递归函数,else中嵌套函数。 执行return满足条件if temp == 1不是最外面的循环,而是else self.isHappy(temp)中 执行的函数,因此return返回的值被返回到了else中,不会返回到最外面一层。
解决:在else中也增加return。
但还是出现了错误,后面有个用例没能通过
memory = []
class Solution:
def isHappy(self, n: int) -> bool:
temp = 0
while n > 0:
temp = temp + (n % 10)**2
n = n // 10
if temp == 1:
return True
elif temp in memory:
return False
else:
memory.append(temp)
return self.isHappy(temp)
因为存储temp是否在之前中出现过的列表memory在class外面,猜测是memory把前面其他用例计算过程中的temp也储存了下来,但不知道怎么修改:放在Solution后isHappy前会报错memory未定义,放在方法内则递归的时候每次都是空,也起不到作用。
正确的递归,在原有的方法内再新建一个方法:
class Solution:
def isHappy(self, n: int) -> bool:
memory = []
def happy(n):
temp = 0
while n > 0:
temp = temp + (n % 10)**2
n = n // 10
if temp == 1:
return True
elif temp in memory:
return False
else:
memory.append(temp)
return happy(temp)
return happy(n)
注:memory = set()这个更快
def isHappy(self, n: int) -> bool:
def get_next(n):
total_sum = 0
while n > 0:
n, digit = divmod(n, 10)
total_sum += digit ** 2
return total_sum
seen = set()
while n != 1 and n not in seen:
seen.add(n)
n = get_next(n)
return n == 1
这里的时间复杂度以及后面的思路分析有点意思,有兴趣的可以点击下面的链接自行查看
def isHappy(self, n: int) -> bool:
def get_next(number):
total_sum = 0
while number > 0:
number, digit = divmod(number, 10)
total_sum += digit ** 2
return total_sum
slow_runner = n
fast_runner = get_next(n)
while fast_runner != 1 and slow_runner != fast_runner:
slow_runner = get_next(slow_runner)
fast_runner = get_next(get_next(fast_runner))
return fast_runner == 1
一些思考:
① 本来认为这个解答有缺陷,因为快指针每次走两步,会漏掉走到1的一步,细看发现,漏掉的那一步如果为1,即get_next(fast_runner)为1,那么get_next(get_next(fast_runner))还是会为1,其实不影响
② 以为存在快指针刚好跳过慢指针从而恰好错过相遇,龟兔一直循环跑的情形,其实不然。在兔快要遇上龟时,有两种情况,兔与龟之间相差一个空位,这时,它们将在下一次走动相遇;如果相差两个空位,那么走动一次后将相差一个空位,即到了前面的情况。
时间复杂度:O(logn)
空间复杂度:O(1)
def isHappy(self, n: int) -> bool:
cycle_members = {4, 16, 37, 58, 89, 145, 42, 20}
def get_next(number):
total_sum = 0
while number > 0:
number, digit = divmod(number, 10)
total_sum += digit ** 2
return total_sum
while n != 1 and n not in cycle_members:
n = get_next(n)
return n == 1
这样的题目还是简单题,而且名字还叫快乐数,我哭死
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/happy-number/solution/kuai-le-shu-by-leetcode-solution/