LeetCode202 快乐数

题目

在这里插入图片描述
刷完快乐数,感到快乐的成本又上升了 T.T

解题

解题思路见:快乐数

关键在于能不能看透判断快乐数的本质:每步计算结果是否会形成环路

在这里插入图片描述
输入满足 1 < = n < = 2 31 − 1 1 <= n <= 2^{31} - 1 1<=n<=2311,最大是 10 位,而 81 ∗ 124 = 10044 , 81 ∗ 123 = 9963 81 * 124 = 10044,81 * 123 = 9963 81124=1004481123=9963。所以 4 - 12 位数,一次运算后变为 3 位数,13 - 123 位数,一次运算后变为 4 位数,两次运算后变为 3 位数,而这些数的个数是大于 243 的,所以一定会形成循环,而只有 1 的各位数平方和是自己本身。

自此快乐数问题转变为了寻找环路的问题。

解题一:用集合检测循环

// javascript
var isHappy = function(n) {
    let seen = new Set();
    while (n !== 1 && seen.has(n) === false) {
        seen.add(n);
        n = getNext(n); // 不能在 n 前加 let
    }
    return n === 1;
};

var getNext = function(x) {
    let sum = 0, cur = 0;
    while (x !== 0) {
        cur = x % 10;
        sum += cur * cur;
        x = parseInt(x / 10);
    }
    return sum;
};

在这里插入图片描述

解题二:快慢指针法

思路参考 LeetCode141 环形链表
在这里插入图片描述
fastRunner 要先走一步(或者用 do while 循环),不然根本进不了 while 循环。

// javascript
var isHappy = function(n) {
    let slowRunner = n;
    let fastRunner = getNext(n); // 先走一步
    while (fastRunner !== 1 && fastRunner !== slowRunner) {
        slowRunner = getNext(slowRunner);
        fastRunner = getNext(getNext(fastRunner));
    }
    return fastRunner === 1;
};

var getNext = function(x) {
    let sum = 0, cur = 0;
    while (x !== 0) {
        cur = x % 10;
        sum += cur * cur;
        x = parseInt(x / 10);
    }
    return sum;
};

在这里插入图片描述

解题三:数学

仅供娱乐:
在这里插入图片描述

// javascript
var isHappy = function(n) {
    let cycle_members = new Set([4, 16, 37, 58, 89, 145, 42, 20]);
    while (n !== 1 && cycle_members.has(n) === false) {
        n = getNext(n);
    }
    return n === 1;
};

var getNext = function(x) {
    let sum = 0, cur = 0;
    while (x !== 0) {
        cur = x % 10;
        sum += cur * cur;
        x = parseInt(x / 10);
    }
    return sum;
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值