第202题:快乐数
描述:
编写一个算法来判断一个数 n 是不是快乐数。
快乐数定义:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19 输出:true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
解题思路:如何判断计算过程是否进入无限循环?
法1:投机解法(避免使用)
- 将输入整数转换为字符串,按照题意进行计算。
- 若不是快乐数则会陷入无尽循环中,设定当循环次数count > 1000 时,返回非快乐数。
法2:哈希集法(检查数字是否在哈希集中需要 O(1) 的时间,而对于其他数据结构(列表等),则需要 O(n) 的时间。)
- 将每次计算得到的整数 n_int 放入到哈希集 seen 中
- 每次计算前判断整数 n_int 是否存在于哈希集中,若存在则已陷入无限循环,返回非快乐数。
法2:快慢指针法(链表思想)
- 维护两个指针:slow(步长1)、fast(步长2)。
- 若陷入无限循环,则两个指针一定会在同一时间相遇(类比龟兔赛跑)。
Python代码:(投机解法)
1 class Solution(object): 2 def isHappy(self, n): 3 """ 4 :type n: int 5 :rtype: bool 6 """ 7 n_int = n 8 count = 0 9 while n_int is not 1 and count < 1000: 10 n_str = str(n_int) 11 sum_all = 0 12 for i in n_str: 13 a = int(i) 14 sum_all += a*a 15 n_int = sum_all 16 count += 1 17 if count == 1000: 18 return False 19 else: 20 return True
Python代码:(哈希集法)
1 class Solution(object): 2 def isHappy(self, n): 3 """ 4 :type n: int 5 :rtype: bool 6 """ 7 n_int = self.get_next(n) 8 seen = set() 9 while n_int is not 1: 10 if n_int not in seen: 11 seen.add(n_int) # 哈希集的 add() 方法 12 n_int = self.get_next(n_int) 13 else: 14 return False 15 return True 16 17 def get_next(self, n): # 此辅助函数充分体现了链表指针的思想 18 n_str = str(n) 19 n_cal = 0 20 for i in n_str: 21 n_cal += int(i) * int(i) 22 return n_cal
Python代码:(快慢指针法)
1 class Solution(object): 2 def isHappy(self, n): 3 """ 4 :type n: int 5 :rtype: bool 6 """ 7 slow = self.get_next(n) 8 fast = self.get_next(slow) 9 while slow is not fast: # is 和 not 的正确使用 10 slow = self.get_next(slow) 11 fast = self.get_next(self.get_next(fast)) 12 if fast == 1: # 循环结束时有两种可能:快慢指针都为 1 、无限循环 13 return True 14 else: 15 return False 16 17 def get_next(self, n): # 此辅助函数充分体现了链表指针的思想 18 n_str = str(n) 19 n_cal = 0 20 for i in n_str: 21 n_cal += int(i) * int(i) 22 return n_cal