快乐数(Java)----哈希表和快慢指针的应用

问题描述:

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

        如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

例如:

        那么如何去判断一个数是否是快乐数呢

                由于快乐数最后变形后是1,那么给定一个数,他经过快乐数的判断步骤的类型有三种:

1.确实经过判断,最终返回1

2.经过不断的平方相加,发现进入了死循环:

3.经过不断的平方相加操作,发现数据无穷大;

        然而第三种情况并不存在,因为若数据为13位的9(9999999999999),然而经过平方相加之后为9*9*13=1053,相当于从13位数变为4位数,所以经过平方相加,并不会使使得数据出现趋于无穷大的情况;

        无论使用哈希表还是快慢指针,首先都需要一个方法,将数据的每一位分开进行平方相加:

 private int getNext(int n) {
        int sum = 0;
        while(n>0){
        int a=n%10;     //取个位
        int b=n/10;       //将个位去除
       sum=sum+a*a;     //累加平方和
                }
        }
        return sum;
    }

       

        使用哈希表解决:

      新建一个哈希表,将每次经过平方相加操作的数据存储到哈希表中,并放入循环之中,判断条件即为:当数据不为1或者此数据在哈希表中不存在(若存在说明死循环已开始);

        如果数据因为运算之后等于1 ,那么和return的n==1便相同,所以返回true;

        如果数据因为已经在哈希表中存在而退出循环,那么此时的n的值肯定和1不同,所以返回false:

    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;   //与1进行比较,若相同则返回true,若不同则返回false
    }

        使用快慢指针:

        因为看到了循环链表的存在,所以可以使用快慢指针,此题由于有getNext方法所以不用创建链表;

        首先定义,快指针和慢指针(在快慢指针循环移动位置时,要对快慢指针所指向的节点进行判断是否相等,所以初始化指针的时候不能将这两个指针定义相同):

        int slowRunner = n;
        int fastRunner = getNext(n);

        然后进入循环体,让慢指针每循环一次移动一位,快指针每循环一次移动两位;循环条件便是慢指针和快指针指向的是不同的元素,或者其中一个指针指向的不是1

     while (fastRunner != 1 && slowRunner != fastRunner) {
            slowRunner = getNext(slowRunner);
            fastRunner = getNext(getNext(fastRunner));
        }
        return n==1;
    

        如果某一个指针指向1,那么久跳出循环,与return的值比较,发现相等,那么就返回true;

        如果两个指针指向同一个元素,那么说明要进入死循环,则跳出循环,与返回的1进行比较,肯定不是1,所以返回false;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Tinkinon

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

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

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

打赏作者

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

抵扣说明:

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

余额充值