202. 快乐数
题目描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
输入:n = 19 输出:true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
示例 2:
输入:n = 2 输出:false
提示:
1 <= n <= 231 - 1
解法
方法一:哈希表 + 模拟
思考
按定义反复取各位平方和即可判定,但序列既可能到达 \(1\),也可能陷入循环。平方和会迅速落入有限范围,因此可用哈希表记录出现过的数。
若再现则存在环、不是快乐数;若变为 \(1\) 则是。模拟与判重同步进行,空间与值域规模相当。
将每次转换后的数字存入哈希表,如果出现重复数字,说明进入了循环,不是快乐数。否则,如果转换后的数字为 \(1\),说明是快乐数。
时间复杂度 \(O(\log n)\),空间复杂度 \(O(\log n)\)。
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
方法二:快慢指针
思考
方法一已能正确判定,但哈希表占用额外空间。平方和变换是确定的函数迭代,环检测不必存全部历史。
为此用快慢指针:慢指针走一步、快指针走两步,相遇时若值为 \(1\) 则是快乐数,从而将空间降为常数。
与判断链表是否存在环原理一致。如果 \(n\) 是快乐数,那么快指针最终会与慢指针相遇,且相遇时的数字为 \(1\);否则,快指针最终会与慢指针相遇,且相遇时的数字不为 \(1\)。
因此,最后判断快慢指针相遇时的数字是否为 \(1\) 即可。
时间复杂度 \(O(\log n)\),空间复杂度 \(O(1)\)。
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |