577 字
3 分钟
算法之快乐数

202.快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果 可以变为 1,那么这个数就是快乐数。 如果 n 是快乐数就返回 true ;不是,则返回 false 。

image-20210613171549533

思路:

1.哈希表

每次都去拆分数字计算平方和,如果和为1,就是快乐数,如果不唯一就存在Map里头。

后面计算发现,如果说不是快乐数得话,计算的值可能会回到之前计算的某个值,也就是Map里头,所以如果说计算的结果,map里头存在,那么说明不是快乐树

/**
* @param {number} n
* @return {boolean}
*/
function sum(n) {
n = n + ''
let sum = 0
for (let num of n) {
sum += num * num
}
return sum
}
var isHappy = function (n) {
let res = sum(n)
let obj = {}
while (res != 1) {
if (res in obj) return false
obj[res] = 1
res = sum(res)
}
return true
}

2.快慢指针

根据题意,我们可以分析如下:

找到快乐数 没有快乐数,形成环路,造成死循环。 其实分析是很容易的,接下来我们看看,如何解题。

首先,我们肯定可以使用哈希表记录过程值,若找到 11,皆大欢喜。

如果在找的过程中,哈希表中已存在当前数,则证明进入了环路,也就是死循环了!

此时,我们就可以判断当前数不是一个快乐数了~

但是,为了降低空间复杂度,我们选择使用快慢指针来解决,流程如下:

创建一个慢指针,一次走一步,再创建一个快指针,一次走两步。 当快慢指针相遇,代表形参环路,该数不是快乐数。 若指针移动过程中,找到了 11,则当前数是一个快乐数。

image-20210613170644838

image-20210613170717617

image-20210613170728576

image-20210613170747791

image-20210613170758347

image-20210613170816336

image-20210613170827279

image-20210613170838148

image-20210613171129939

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;
};
算法之快乐数
https://nollieleo.github.io/posts/算法之快乐数/
作者
翁先森
发布于
2021-06-13
许可协议
CC BY-NC-SA 4.0