「快乐数」定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 true ;不是,则返回 false 。
- 简单来说快乐数就是历经人间曲折可以得到(1)
比如:19
1^2 + 9^2 = 82;
8^2 + 2^2 = 68;
6^2 + 8^2 = 100;
1^2 + 0^2 + 0^2 = 1;
最终19经历了4次转换,得到了1,定义19就是个快乐数;
快乐数的快乐你get到了吗?
什么是不快乐数呢?
比如:2
- 2^2 = 4;
- 4^2 = 16;
- 1^2 + 6^2 = 37;
- 3^2 + 7^2 = 58;
- 5^2 + 8^2 = 89;
- 8^2 + 9^2 = 145;
- 1^2 + 4^2 + 5^2 = 42;
- 4^2 + 2^2 = 20;
- 2^2 + 0^2 = 4;
看看,看看第1步和第9步的结果一致,是不是要进入一个循环了;
4、16、37、58、89、145、42、20、4......
自循环,当然再也得不到1;
通过上述两个比如 是不是一直循环计算直到新的数是1或者之前出现过的数结束条件
- 分解:
- 首先写一个获取整数每一位数的平方和算法:
const getNumber = (n) => {
let res = 0
do {
const a = n % 10
n = (n - a) / 10
res += a * a
} while( n >= 10)
res += n * n
return res
}
PS:也曾尝试过将整数转换为字符串数组,然后分别对每个元素取得平方再相加,但性能方面比整数计算要低一些。
如何判断交点以及每次计算结果是否为1呢?
可以将每一次的计算结果和1做比对,如果为1,那么就是快乐数,eturn true.如果不为1,那么将该数存在一个数组里面,并且继续进行 getNumber() 的操作。每一次操作后都会和1比对并且查看数组里面是否存在过该数,如果存在那么表示有相交,return false
/**
* @param {number} n
* @return {boolean}
*/
const getNumber = (n) => {
let res = 0
do {
const a = n % 10
n = (n - a) / 10
res += a * a
} while( n >= 10)
res += n * n
return res
}
var isHappy = function(n) {
let list = []
while(true) {
n = getNumber(n)
if (n === 1) {
return true
} else if (list.indexOf(n) !== -1) {
return false
}
list.push(n)
}
};