[路飞]_leetcode_202.快乐数

140 阅读1分钟

思考

「快乐数」定义为:

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

示例 1:

输入:n = 19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

通过示例 1我们可以将快乐数以链表的形式展现

19 -> 82 -> 68 -> 100 -> 1

以 37 为例:

37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37 -> 58 ->...

得 37 不是快乐数,那么最终所展示的链表为环形链表

解题思路

通过判断环形链表得方式,反推判断不是环形链表

代码

/**
 * n = 19
 * 1^2 + 9^2 = 82
 */
function getNext(n) { // n = 19
    let s = 0; 
    while( n > 0) {
        s += ( n % 10 ) * ( n % 10 ); // 对n取余: 9^2 / 1^2
        n = Math.floor( n / 10 ); // Math.floor( 1.9 ) = 1 / Math.floor( 0.1 ) = 0
    }
    return s; // s = 9^2 + 1^2
}

function isHappy (n) {
    // 如果 n = 1 那么 n 就是快乐数
    if (n == 1 ) return true;

    // 通过模拟快慢指针的方式判断不是环形链表
    let fast = slow = n;
    do {
        fast = getNext(getNext(fast));
        slow = getNext(slow);
    } while (fast !== slow && fast !== 1) 
    /**
     * 1. 当快慢指针相等时,表示该数不是快乐数
     * 2. 当快指针走到1的位置,表示该数是快乐数
     */
    return fast == 1
}