[路飞]_快乐数

322 阅读1分钟

题目描述

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

「快乐数」定义为:

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

leetcode-202 快乐数

题目分析

从题目上来看,我们可以用链表的思想来对这道题做一下翻译:

当这个过程最后会变为 1,可以类比为一条没有环的链表,1 就是最后的空节点

1639318070(1).png

当这个过程无限循环但始终变不到 1时,可以想象成是一个带环的链表

1639318261(1).png

解题思路一(Map)

既然可以用环形链表的思路来解题,那么解题的方法也跟环形链表的解法一样,不清楚的可以看我前面的文章
[路飞]_环形链表
[路飞]_环形链表II

代码

/**
 * @param {number} n
 * @return {boolean}
 */
var isHappy = function(n) {
    if (n === 1) return true
    const mapper = new Map()
    let p = getNext(n)
    while (p !== 1) {
        if(!mapper.has(p)) {
            mapper.set(p, p)
            p = getNext(p)
        } else {
            return false
        }
    }
    return true
};

var getNext = function(n) {
    let sum = 0
    while(n) {
        sum += (n % 10) ** 2
        n = Math.floor(n / 10)
    }
    return sum
}

解题思路二(快慢指针法)

代码

/**
 * @param {number} n
 * @return {boolean}
 */
var isHappy = function(n) {
    if (n === 1) return true
    let p = getNext(n)
    let q = getNext(getNext(n))
    while (p !== q && q !== 1) {
        p = getNext(p)
        q = getNext(getNext(q))
    }
    return q === 1
};

var getNext = function(n) {
    let sum = 0
    while(n) {
        sum += (n % 10) ** 2
        n = Math.floor(n / 10)
    }
    return sum
}