[路飞]leetcode-202.快乐数

218 阅读3分钟

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

题目描述

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

「快乐数」定义为:

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

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

题解1-Map方案

思路分析

题目中讲,输入有两种情况,无限循环 或者 变为1

我们可以分析,所有数字最大也就是 1 ~ 9,因此按此规则枚举出来的最大值的平方也就是 8^2 + 1^2,

可以分析出来,无限循环其实是有规则的,因此可以使用map来记录你已经计算出来的数据

每次计算出来的值有没有在map中现过

如果有重复数据,则此数无限循环

如果存在1,那么此数为快乐数

return false || true

代码实现

var isHappy = function (n) {
    const mapper = new Map();
    let newNum = n;
    let sum = 0;
    while (newNum || sum !== 1) {
        if (newNum === 0 && sum !== 1) {
            if (mapper.has(sum)) {
                return false;
            } else {
                mapper.set(sum, true);
            }
            newNum = sum;
            sum = 0;
        }
        sum = Number(sum) + Number(newNum % 10) * Number(newNum % 10);
        newNum = Math.floor(newNum / 10);
    }
    return sum === 1;
};

题解2-链表思维描述

处理算法实际就是在锻炼代码思维,因此也会将链表思路分析在下文,可以提升大家的代码修养,并且这个解法也非常的有趣。

思路分析

我们先分析题目,每次将该数的结果输出在一个链表结构中,假设分别输入进去的数字为,19 、 2,那么我们可以得到如下数据结构

19: 19 —> 82 —> 68 —> 100 —> 1

2: 2 —> 4 —> 16 —> 37 —> 58 —> 89 —> 145 —> 42 —> 20 —> 4 —> 16 —> 37

这些数据组成了一个数据上的链表。

先分析存在1的情况,存在1的话,那么我们只需要将计算过的数据放在一个变量之中,判断变量为1,return true。

假设不存在1呢?

我们来分析数据的规则,按照第二个数据结构来推测,如果数据没有推算出来1,则个位数的平方和是按照某种规则来循环生成数据的。(可能存在某种数学公式或者数学上的专业语言,作者暂时不清楚,欢迎大神评论区指导)。

因此上面的数据结构,可以归并为链表运算算法中的一道经典题目,链表探环之前文章指路

链表探环处理中有一种经典的解决方案,快慢指针,因此我们就采用此思路来整理此题

大概代码结构

1、创建一个方法,功能是根据传入数据按照规则生成下一位数据。

2、采用快慢指针思路,两个变量,分别用于存储当前数据和下一个数据。

3、创建一个循环,循环中每次循环,快指针走一步,慢指针走两步

4、根据最终循环结果来判断,生成的数据是否循环(链表探环),最终返回对应值

代码实现

const isHappy = (num) => {
    const getNextNum = (n) => {
        const nextNum = 0;
        while(n) {
            curNum += (n % 10) * (n % 10);
            n = Math.floor( n / 10);
        }
        
        return nextNum;
    }
    
    let startNum = n, nextNum = getNextNum(n);
    do {
        startNum = getNext(start);
        nextNum = getNext(getNext(nextNum));
    } while(startNum !== nextNum && nextNum !== 1);
    
    return nextNum === 1;
}

github指路