掘金团队号上线,助你 Offer 临门! 点击 查看详情
题目描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果 可以变为 1,那么这个数就是快乐数。 如果 n 是快乐数就返回 true ;不是,则返回 false 。
提示: 1 <= n <= 2^31 - 1
解题思路
拿到题目先看几种可能性:
-
最终得到1
-
最终无限循环
-
数越加越大,无限不循环 第一种和第二种比较好证明,如何证明第三种情况会不会出现呢?在题目中有一个提示,说这个n <= 2^31 - 1(n<=2147483647),在这个区间内,平方和最大的数是1999999999,而这个数的平方和为730,也就是说,最大也不会超过730。所以可以说明,第三种情况不存在,我们不需要考虑。 不考虑第三种情况,这道题就简单多了,变成了一道判断链表是否有环的题,之前有做过一道判断环形链表是否有环的题目(题号:141),而这道题,只不过多了一个计算平方和的方法。方法步骤如下:
-
定义两个指针,快指针和慢指针;
-
当变到1时,说明链表没有环,快慢指针永远不会相遇,返回true;
-
当限于循环时,说明链表有环,快慢指针必定会在环内相遇,返回false;
解题代码
var isHappy = function (n) {
let slow = n, fast = n;
while (fast !== 1 && getNext(fast) !== 1) {
slow = getNext(slow);
fast = getNext(getNext(fast));
if (slow === fast) {
return false;
}
}
return true;
};
// 计算平方和
function getNext(n) {
return String(n).split('').reduce((pre, cur) => pre + cur * cur, 0);
}
总结
解题的时候要考虑清楚题目所有可能的情况,能够利用曾经学过的数据结构进行举一反三