LeetCode 202

题目202. 快乐数

在这里插入图片描述


解法一:快慢指针

题目中提到在计算快乐数时,会出现无限循环的情况,因此遍历时需要判断是否存在循环,若存在循环则跳出循环。而各个位数相加为1也是一个循环,因为12=1,会持续循环下去,那么当我们跳出循环时,判断循环的原因是否由1引起,若是如此,该数即为快乐数。

class Solution {

    public boolean isHappy(int n) {
        int slow = n, fast = n;
        do {
            slow = getNext(slow);
            fast = getNext(fast);
            fast = getNext(fast);
        } while (slow != fast);
        return slow == 1;
    }

    public int getNext(int n) {
        int bit, res = 0;
        while (n != 0) {
            bit = n % 10;
            res += bit * bit;
            n /= 10;
        }
        return res;
    }
}

注意点

  1. 整型最大13位,当每位都为9时,各位的平方和最大为1053,而再求下一个平方和时,一定不会超过1053,所以,若有循环,则一定会在该范围出现,而不会出现计算出无穷大的情况
  2. 当需要判断是否出现循环时,可以使用快慢指针算法
  3. 判断是否为快乐数,只需判断循环的原因是否由1引起
  4. 在进入循环后,快慢指针会出现3种情况
    • fast在后,slow在前,相距1格,下次相遇。
    • fast在后,slow在前,相距2格,下一次移动,变为相距1格。
    • 其它时刻,每次环内移动,距离缩短1,直至相距2格。
  5. 快慢指针相遇位置一定在入环点

快慢指针参考:深入理解快慢指针算法 – 链表环路检测 - 知乎 (zhihu.com)


解法二:哈希表检测循环

将每次遍历到的数字存在hash表中,当存入数字和已有数字重复时,判断存在循环,判断循环元素是否为1,为1则代表该数为快乐数

class Solution {
    private int getNext(int n) {
        int totalSum = 0;
        while (n > 0) {
            int d = n % 10;
            n = n / 10;
            totalSum += d * d;
        }
        return totalSum;
    }

    public boolean isHappy(int n) {
        Set<Integer> seen = new HashSet<>();
        while (n != 1 && !seen.contains(n)) {
            seen.add(n);
            n = getNext(n);
        }
        return n == 1;
    }
}

注意:第一个重复的元素即为入环点,看上图理解


  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值