LeetCode202.快乐数

题目链接202. 快乐数 - 力扣(LeetCode)

知识点补充:

根据鸽巢原理,当一个数求其每一位的平方的和时,总会出现循环,即每一位平方的和均为其本身,这又两种情况,一是和为1,接下来怎么求都是1;二是和为其他数,但每一位的平方的和均为其本身。

1.常规解法

将每一个数的每一位的平方的和求出后放到一个顺序表中,每一次都判断该数时候存在于顺序表中,若存在,则判断是否为1,若为1,则是快乐数,返回true;若不是,则不是快乐数,返回false,代码如下:

    public boolean isHappy(int n) {
        ArrayList<Integer> list = new ArrayList<>();
        int num = n;
        while (true) {
            num = getNum(num);
            if (list.contains(num)) {
                if (num == 1) {
                    return true;
                } else {
                    return false;
                }
            }
            list.add(num);
        }
    }

    public int getNum(int n) {
        int num = 0;
        while (n != 0) {
            num += (n % 10) * (n % 10);
            n /= 10;
        }

        return num;
    }

说明:getNum方法即求n的每一位的平方的和。

2.双指针算法

根据前面的知识补充,可知无论怎么求,最后都会是一下图:

学过链表的同学应该都对这张图不陌生,和判断链表是否有环一样,都有一个循环,这是我们就可以根据快慢指针来判断是否有环,若两指针相遇,即有环,反之则无环。

这题也是一样,我们可以定义两个“指针”slow和fast,slow一次走一步,相当于求一次每一位的平方的和,fast一次走两步,相当于求两次每一位的平方的和,根据上述补充知识,该循环一定有环,即fast与slow一定会相遇,只需要判断相遇的时候fast或slow的值是不是1即可,若为1,则为快乐数,返回true,若不为1,则不是快乐数,返回false,代码如下:

    public boolean isHappy(int n) {
        int slow = n;
        int fast = getNum(getNum(n));
        while (fast != slow) {
            slow = getNum(slow);
            fast = getNum(getNum(fast));
        }
        
        if (fast == 1) {
            return true;
        } else {
            return false;
        }
    }

    public int getNum(int n) {
        int num = 0;
        while (n != 0) {
            num += (n % 10) * (n % 10);
            n /= 10;
        }
        return num;
    }

 需要注意的是,一开始定义fast和slow时,不能让两个都为n,因为都为n后,循环就进不去了,可以让fast先走两步,这样就能进入循环了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值