模块一——双指针:202.快乐数

题目描述

题目链接:202.快乐数
在这里插入图片描述
为了方便叙述,将对于⼀个正整数,每⼀次将该数替换为它每个位置上的数字的平方和这⼀个操作记为x操作;
题目告诉我们,当我们不断重复操作的时候,计算⼀定会「死循环」,死循环的方式有两种:

  1. 情况⼀:⼀直在1中死循环,即1 -> 1 -> 1 -> 1…
  2. 情况⼆:在历史的数据中死循环,但始终变不到1

由于上述两种情况只会出现⼀种,因此,只要我们能确定循环是在情况⼀中进行中,还是在情况二中进行,就能得到结果。

简单证明

  1. 经过⼀次变化之后的最⼤值92 *10 = 810 ( 231-1=2147483647 。选⼀个最大的9999999999 ),也就是变化的区间在[1, 810] 之间;
  2. b. 根据「鸽巢原理」,⼀个数变化811 次之后,必然会形成⼀个循环;
  3. 因此,变化的过程最终会⾛到⼀个圈⾥⾯,因此可以⽤「快慢指针」来解决。

补充知识

如何求⼀个数n每个位置上的数字的平⽅和。

a.把数n 每⼀位的数提取出来:
循环迭代下⾯步骤:

  • int t = n % 10 提取个位;

  • n /= 10 ⼲掉个位;

直到n 的值变为0 ;
b. 提取每⼀位的时候,⽤⼀个变量tmp 记录这⼀位的平⽅与之前提取位数的平⽅和
tmp = tmp + t * t

算法原理

根据上述的题⽬分析,我们可以知道,当重复执⾏x 的时候,数据会陷⼊到⼀个「循环」之中。⽽「快慢指针」有⼀个特性,就是在⼀个圆圈中,快指针总是会追上慢指针的,也就是说他们总会相遇在⼀个位置上。如果相遇位置的值是1 ,那么这个数⼀定是快乐数;如果相遇位置不是1 的话,那么就不是快乐数。

代码实现

class Solution {
public:
    int bitSum(int n)//返回n这个数每一位上的平方和
    {
        int sum = 0;
        while(n)
        {
            int tmp = n % 10;
            sum += tmp * tmp;
            n = n / 10;
        }
        return sum;
    }

    bool isHappy(int n) {
        int slow = n,fast = bitSum(n); //定义快慢指针

        while(slow != fast)//快指针走两步,慢指针走一步
        {
            slow = bitSum(slow);
            fast = bitSum(bitSum(fast));
        }

        return slow == 1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

全天

加油,大佬们!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值