携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
题目(Happy Number)
链接:https://leetcode-cn.com/problems/happy-number
解决数:2113
通过率:63%
标签:哈希表 数学 双指针
相关公司:jpmorgan google amazon
编写一个算法来判断一个数 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
思路
根据题意,我们可以分析如下:
- 找到快乐数
- 没有快乐数,形成环路,造成死循环。
其实分析是很容易的,接下来我们看看,如何解题。
首先,我们肯定可以使用哈希表记录过程值,若找到 ,皆大欢喜。
如果在找的过程中,哈希表中已存在当前数,则证明进入了环路,也就是死循环了!
此时,我们就可以判断当前数不是一个快乐数了~
但是,为了降低空间复杂度,我们选择使用快慢指针来解决,流程如下:
- 创建一个慢指针,一次走一步,再创建一个快指针,一次走两步。
- 当快慢指针相遇,代表形参环路,该数不是快乐数。
- 若指针移动过程中,找到了 ,则当前数是一个快乐数。
🍭 示例代码
let getNext = function (n) {
return n.toString().split('').map(i => i ** 2).reduce((a, b) => a + b);
}
let isHappy = function (n) {
let slow = n;
let fast = getNext(n);
while(fast !== 1 && fast !== slow){
slow = getNext(slow);
fast = getNext(getNext(fast));
}
return fast === 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
class Solution {
public int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}
public boolean isHappy(int n) {
int slowRunner = n;
int fastRunner = getNext(n);
while (fastRunner != 1 && slowRunner != fastRunner) {
slowRunner = getNext(slowRunner);
fastRunner = getNext(getNext(fastRunner));
}
return fastRunner == 1;
}
}
class Solution {
public int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}
public bool IsHappy(int n) {
int slowRunner = n;
int fastRunner = getNext(n);
while (fastRunner != 1 && slowRunner != fastRunner) {
slowRunner = getNext(slowRunner);
fastRunner = getNext(getNext(fastRunner));
}
return fastRunner == 1;
}
}
func isHappy(n int) bool {
slow, fast := n, step(n)
for fast != 1 && slow != fast {
slow = step(slow)
fast = step(step(fast))
}
return fast == 1
}
func step(n int) int {
sum := 0
for n > 0 {
sum += (n%10) * (n%10)
n = n/10
}
return sum
}