[路飞]LeetCode(202)-快乐数

179 阅读2分钟

「快乐数」定义为:

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

 - 简单来说快乐数就是历经人间曲折可以得到(1

比如:19
1^2 + 9^2 = 82;
8^2 + 2^2 = 68;
6^2 + 8^2 = 100;
1^2 + 0^2 + 0^2 = 1;
最终19经历了4次转换,得到了1,定义19就是个快乐数;
快乐数的快乐你get到了吗?

什么是不快乐数呢?
比如:2

  1. 2^2 = 4;
  2. 4^2 = 16;
  3. 1^2 + 6^2 = 37;
  4. 3^2 + 7^2 = 58;
  5. 5^2 + 8^2 = 89;
  6. 8^2 + 9^2 = 145;
  7. 1^2 + 4^2 + 5^2 = 42;
  8. 4^2 + 2^2 = 20;
  9. 2^2 + 0^2 = 4;

看看,看看第1步和第9步的结果一致,是不是要进入一个循环了;
4、16、37、58、89、145、42、20、4......

自循环,当然再也得不到1;

通过上述两个比如 是不是一直循环计算直到新的数是1或者之前出现过的数结束条件

  • 分解:
    • 首先写一个获取整数每一位数的平方和算法:
const getNumber = (n) => {
    let res = 0
    do {  
        const a = n % 10
        n = (n - a) / 10
        res += a * a
    } while( n >= 10)
    res += n * n
    return res
}

PS:也曾尝试过将整数转换为字符串数组,然后分别对每个元素取得平方再相加,但性能方面比整数计算要低一些。

如何判断交点以及每次计算结果是否为1呢?

可以将每一次的计算结果和1做比对,如果为1,那么就是快乐数,eturn true.如果不为1,那么将该数存在一个数组里面,并且继续进行 getNumber() 的操作。每一次操作后都会和1比对并且查看数组里面是否存在过该数,如果存在那么表示有相交,return false

/**
 * @param {number} n
 * @return {boolean}
 */

const getNumber = (n) => {
    let res = 0
    do {  
        const a = n % 10
        n = (n - a) / 10
        res += a * a
    } while( n >= 10)
    res += n * n
    return res
}

var isHappy = function(n) {
    let list = []
    while(true) {
      n = getNumber(n)
      if (n === 1) {
          return true
      } else if (list.indexOf(n) !== -1) {
         return false
      }
      list.push(n)
    }
};

微信图片_20211210072120.png