前言
刚看到看到这个题的时候,我是非常不快乐的。
但是在以后的面试遇到这道题的时候,我想我会是非常快乐的。
一、题目描述
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。
- 如果可以变为1,那么这个数就是快乐数。
如果 n 是快乐数就返回
true;不是,则返回false。
二、解题思路
本质还是链表判环,根据链表唯一指向来做。不会链表判环的可以先看我的之前写的用JavaScript刷leetcode第141题-链表是否有环这篇文章。
- 把1当成尾节点,因为1的平方和始终为1,会一直指向本身
- 无论有环还是无环时返回
f === 1,快慢指针相遇了,说明快指针已经至少走了环一圈了,走了一圈没得到1,有人可能会说直接返回false,但我这么写也没毛病,还可以节省后面无环结果为1的代码。 - 有人可能会说这个链表有没有可能没有尽头,其实并不会。因为他不会一直变大,也不会一直变小。
三、代码
列两种写法,仅仅只是代码精简度不一样,并不是第二种解法
1.常规写法
var isHappy = function(n) {
let s = n;
let f = n;
while(f !== 1 && getSquareSum(f) !== 1) {
s = getSquareSum(s);
f = getSquareSum(getSquareSum(f));
if(s === f) return false;
}
return true;
};
function getSquareSum(n) {
let res = 0;
while(n) {
res += (n % 10) ** 2
n = Math.floor(n / 10)
}
return res;
}
2.用return f === 1 的写法
var isHappy = function(n) {
let s = n;
let f = n;
do{
s = getSquareSum(s);
f = getSquareSum(getSquareSum(f));
} while(f !== 1 && f !== s)
return f === 1;
};
function getSquareSum(n) {
let res = 0;
while(n) {
res += (n % 10) ** 2
n = Math.floor(n / 10)
}
return res;
}