[路飞]_前端算法第十三弹-202. 快乐数

301 阅读2分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

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

「快乐数」定义为:

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

如果 n 是快乐数就返回 true ;不是,则返回 false 。

这道题的关键就在于判断其平方和是不是一个无限循环,所以我们只要看出现的值以前有没有出现过即可。

所以我们想到了使用hash数组来进行存储。

var isHappy = function(n) {
// 新建一个hash数组
let set = new Set();
如果n=1了,或者出现循环了,遍历结束
while(n!=1&&!set.has(n)){
		// 将新值存入hash
    set.add(n);
		继续遍历
    n=getNext(n)
}
return n==1
};

var getNext = function(n){
// 计算各个元素的平方和
    let total = 0;
    n=n.toString()
    for(let i=0;i<n.length;i++){
        total = total+n[i]*n[i]
    }
    return total*1
}

如果我们把数字n,想象成一个单链表的话,如果出现循环则这个链表就是一个循环链表,这就可以用到我们之前写的另一道题,循环链表。我们只需要建立一个快慢指针,如果快慢指针相等,那证明出现了循环。

var 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
};

// 计算各个元素的平方和
var getNext = function(n){
    n = n.toString();
    let total =0;
    for(let i = 0;i<n.length;i++){
        total = total+n[i]*n[i]
    }
    return total*1
}