1.18每日一题

题目描述

题目链接:202.快乐数

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

示例 1
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2
输入:n = 2
输出:false

提示

  • 1 <=n<= 231 - 1

解题核心

循环链表问题,无论输入什么数,它的结果不是1就是在无限循环

DigitsLargestNext
1981
299162
3999243
49999324
1399999999999991053

对于3位数的数字,它不可能大于243。这意味着它要么被困在243以下的循环内,要么跌到14位或4位以上的数字在每一步都会丢失一位,直到降到3位为止。所以我们知道,最坏的情况下,算法可能会在 243以下的所有数字上循环,然后回到它已经到过的一个循环或者回到1,但它不会无限期地进行下去,所以我们排除第三种选择。

解法一:快慢指针

当快指针指向的结果为1或者被慢指针追上的时候可以结束操作,相当于把问题转换成链表是否有环

public boolean isHappy(int n) {
    int slow = n;
    int fast = SquaresSum(n);
    while (fast != 1 && slow != fast) {
        slow = SquaresSum(slow);//慢指针走一步
        fast = SquaresSum(SquaresSum(fast));//快指针走两步,1的平方和还是1,不影响
    }
    return fast == 1;
}
public int SquaresSum(int num) {
    int sum = 0;
    while (num > 0) {
        sum += (num % 10) * (num % 10);
        num /= 10;
    }
    return sum;
}

解法二:数学逻辑

显然题目的无限循环是在一个圈内循环,可以发现10以内只有1和7为快乐数,而循环无论如何都会进入到10以内

public boolean isHappy1(int n) {//能凑到10^n就是快乐数,10以内只有1和7为快乐数
    while (true) {
        if (SquaresSum(n) != 1) {
            n = SquaresSum(n);
        } else {
            return true;
        }
        if (n < 10 && n > 1 && n != 7) {
            return false;
        }
    }
}
public int SquaresSum(int num) {
    int sum = 0;
    while (num > 0) {
        sum += (num % 10) * (num % 10);
        num /= 10;
    }
    return sum;
}

我们去推导可以发现,这个循环会存在规律4->16->37->58->89->145->42->20->4,只要进入到这个循环就一定不是快乐数

public boolean isHappy3(int n) {
    Set<Integer> cycleMembers = new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));
    while (n != 1 && !cycleMembers.contains(n)) {
        n = SquaresSum(n);
    }
    return n == 1;
}
public int SquaresSum(int num) {
    int sum = 0;
    while (num > 0) {
        sum += (num % 10) * (num % 10);
        num /= 10;
    }
    return sum;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伊天凌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值