[路飞]_快乐数

174 阅读1分钟

1. 判断是否为快乐数。

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

此题忽然接触时会有满脸问号的感觉,不要着急,我们细细观察示例;

image.png

每一个数字对应一个结果,当我们把19看为头部,那82则为对应的下一个节点,依次类推,我们发现,这好像和链表结构很相似,那我们把结果为1的看为null,此时便可成为一个每个节点的数据与指针相同的的链表。 没错,我们的解题思路出来了

1.1 借助哈希表

解题思路:

  • 哈希表存遍历过的数字,每遍历一个数字,都查看哈希表是否存在当前数字,如果存在,则说明数字已经开始循环
  • 如果不存在,则存入哈希表,继续遍历

代码实现如下:

var isHappy = function(n) {
    if (n == 1 || n == 0) return n;

    let obj = {}
    let m = n + ''
    while(m !== 1){
        let sum = 0

        for(let i = 0; i < m.length; i++){
            sum += m[i] * m[i]
        }
        if(sum === 1) return true
        if(obj[sum+'']) return false //如果obj中此值为真,则会不断循环,以为进入环形链表中        
        obj[sum+''] = true
        m = sum+''
    }
};

1.2 快慢指针法

解题思路:

  • 使用追击问题的思路
  • 一个快指针与一个慢指针同事从头部出发,慢指针走一格,快指针走两格
  • 如果出现快慢指针相同时,则说明数字已经开始循环

代码实现如下:

let getNext = function (n) {
  // 获得下一个快乐数
  return n
    .toString()
    .split("")
    .map((i) => i ** 2)
    .reduce((a, b) => a + b);
};
/**
 * @param {number} n
 * @return {boolean}
 */
var isHappy = function(n) {
  pre = n, cur = n
  while (cur !== 1 && cur !== pre) {
    pre = getNext(slow);
    cur = getNext(getNext(fast));
  }
  return cur === 1;
};