快乐数

 

对于一个数n一直进行取位置上的数字进行平方和的计算,会有三种情况

1、最终计算结果为1

2、计算出的某一结果为之前已经计算的结果,即出现了循环圈

3、出现无限不循环的情况

对于第三种情况

当n为三位数时,计算出的平方和不大于243

当n为四位数时,最大平方和为324 < 999,再一步计算出的平方和小于243

当n为四位数即以上位数时,计算出的平方和位数远小于数n,也就是取值被大大缩小。例如十三位数的n下一步的最大平方和1053 < 9999,再下一步的平方和小于324 < 999,再下一步的平方和小于243

于是我们可得,数字n进行不断取值平方和的计算,可能会在243下的所有数字内循环或是最终结果为1,不可能存在无限不循环的情况

因此,题目就变为了判断是否出现了循环圈,有两种方法

1、用HashSet存放每个出现过的n,判断是否重复

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class HappyNum {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            int n = scanner.nextInt();
            HappyNum h = new HappyNum();
            System.out.println(h.isHappy1(n));
        }
    }

    public int caculate(int n) {  //计算下一步的平方和
        int num = 0;
        while (n != 0) {
            num += (n % 10) * (n % 10);
            n /= 10;
        }
        return num;
    }

    //用HashSet存放每个出现过的n,判断是否重复
    public boolean isHappy1(int n) {
        Set<Integer> set = new HashSet<>();  //存放每个出现过的n

        while (n != 1) {
            if (set.contains(n)) {  //如果n曾经出现过,说明会出现循环,返回false
                return false;
            } else {  //如果n未曾出现过,则加入set
                set.add(n);
            }
            n = caculate(n);  //把n更新为每一位的平方和
        }
        return true;
    }
}

 

2、快慢指针法

由于只存在两种情况,存在最终结果为1的链表为单向线性的,快跑者的“速度”大于慢跑者,那么快跑者一定先到达1 ;如果最终结果为循环,那么一定在某个时间,快跑者会倒追慢跑者一圈,二者相遇

注意点:快指针每次跳两个不用担心跳过1的点,因为1的点的下一个点还是1

              快指针在慢指针后一个位置出发,这是因为只要求可追击,不要求环形列表的起始点。

    public boolean isHappy2(int n) {
        int fast = n, slow = n;  
        //这里设定二者从同一起点出发,但实际上只需要保证快跑者的起点在慢跑者的起点之后即可

        while(fast != 1 && slow != 1){
            fast = caculate(caculate(fast));  //快指针计算两次平方和
            slow = caculate(slow);  //慢指针计算一次平方和

            if(fast == slow && fast != 1){  //二者相遇并且快跑者的点位不为1
                return false;
            }
        }
        return true;
    }

 

[数学规律] 202. 快乐数(寻找数学规律、判断是否无限循环:Set、快慢指针法)_m0_38142029的博客-CSDN博客_快乐数怎么找

https://leetcode.cn/problems/happy-number/solutions/224894/kuai-le-shu-by-leetcode-solution/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值