《剑指offer》【剑指Offer 43.1 ~n整数中1出现的次数】

🏆个人主页企鹅不叫的博客

​ 🌈专栏

⭐️ 博主码云gitee链接:代码仓库地址

⚡若有帮助可以【关注+点赞+收藏】,大家一起进步!



💎一、题目

🏆1.题目描述

在这里插入图片描述

🏆2.原题链接

剑指Offer 43.1 ~n整数中1出现的次数

💎二、解题报告

🏆1.思路分析

🔑思路:
参考:【动画模拟】我太喜欢这个题了

​ 我们要统计1出现的次数,我们只要将每一个位上面的1的个数统计出来就可以了。
假设这个数是n,那么我们直接遍历n的每一个就可以求出1的个数
我们设置当前指向的数位置是位因子,定义左边为高位,右边为低位,count为1出现的次数,cur为当前位因子的数字,num表示当前位因子的位数。
在这里插入图片描述

下面我们就要讨论当前位(cur==0 ),cur ==1, cur>1三种情况,我们用n ==1004举例
当cur = 0时, n == 1004
小于1004的情况下,最小的为10,最大的为919,高两位出现的情况有00~09十种情况,低位上也有0 ~ 9十种情况,所以
count = numhigh
其实就是0010~0919中,固定住中间的1,移动其他几个,看看有多少种组合
当cur == 1时, n == 1014
十位上为1的最小数字为10,十位上为1的最大数字是1014,所以范围就是10~1014,我们只要固定住十位上面的1,移动其他位置就好了。
我们将1014分成两段,也就是0000~1004,和1005 ~ 1014,前面一段中十位出现1的情况我们已经知道如何求得,为10
10 == 100次,当1004 ~ 1014这一段中十位为1的情况,这一段中最小位出现1的数为1010,最大为1014,此时高位不动,低位可以是0 ~ 4,就是五种情况,低位+1
当cur > 1时, n == 1024
其中最小的为 0010,最大的为 1019
我们也可以将其拆成两段 0010 ~ 0919,1010 ~ 1019,高位数字 * num + num, 10 * 10 + 10 得到 1 出现的次数

🏆2.代码详解

class Solution {
public:
    int countDigitOne(int n) {
        int hight = n;
        int low = 0;
        int count = 0;
        long long num = 1;
        int cur = 0;
        while(hight != 0 || cur != 0)
        {
            cur = hight%10;
            hight /= 10;
            if(cur == 0) count += hight*num;
            else if(cur == 1) count += hight*num+1+low;
            else count += num*(hight+1);
            low = cur*num+low;
            num *= 10;
        }
        return count;
    }
};

hight是高位,low是低位,count是计数,num是当前位因子的位数,cur是当前位因子
之后就是取出cur一位一位比较,然后依次移动hight和low和num
最后返回count


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

penguin_bark

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

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

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

打赏作者

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

抵扣说明:

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

余额充值