[路飞]_夜寻快乐数

511 阅读2分钟

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

202. 快乐数

快乐数为什么会快乐?因为快乐数历经千辛万苦可以得到你(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或者之前出现过的数结束条件呀?

编辑代码

var isHappy = function (n) {
  // 将数通过一定操作的到新的数
  function nextNum(num) {
    let t = 0
    while (num) {
      t += Math.pow(num % 10, 2)
      num = Math.floor(num / 10)
    }
    return t
  }
  
  //声明一个空表
  const set = new Set()
  while (1) {
      // 如果新数据为1;当前数是快乐数
    if (n === 1) return true;
    
    //如果此数已经出现过,进入了循环,当前数不是快乐数
    if (set.has(n)) return false// 将数据放在表中
    set.add(n)
    //调用nextNum获取新数
    n = nextNum(n)
  }
}

循环+哈希表总是那么的顺畅;现在利用了哈希表这个额外空间,哪有没有不使用额外空间的方法呢?

快慢指针

为什么想到快慢指针?

观察两个 比如 运行的结果

graph LR
19 --> 82 --> 68 --> 100 --> 1
graph LR
2 --> 4 --> 16 --> 37 --> 89 --> 145 --> 42 --> 20 --> 4

这不就是判断链表是否有环吗? 思路参看

141. 环形链表

根据环形链表的思路编辑代码如下

var isHappy = function(n) {
    function nextNum(num){
        let t = 0;
        while(num){
            t += Math.pow(num%10,2)
            num = Math.floor(num/10)
        }
        return t;
    }
    
    // 慢指针
    let slow = n;
    // 快指针
    let fast = nextNum(n);
    while(slow !== fast){
        // 慢指针走一步
        slow = nextNum(slow);
        // 快指针走两步
        fast = nextNum(nextNum(fast))
    }
    // 两个指针相等时,慢指针是否为1即可得到答案
    return slow === 1

};