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

题目链接

https://leetcode.cn/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/

思路

三种情况,都可以由cur=0演化而来。
1)当cur=0时,以23045为例子,求百位位置上出现1的次数。此时可选范围是00100—22199,high有23种排列组合,low有100种排列组合,所以百位位置上出现1的次数总数为:23x100–>即highxdigit;

2)当cur=1时,以23145为例子,求百位上出现1的次数。此时可以把0-23145拆分成两项:0-23045以及23046-23145。那么0-23045可以由第一种情况得出结果:highxdigit=23x100。剩下的工作就是求23046-23145中百位出现1的次数,显然只有23100~23145才满足要求,所以第二项的结果就是low+1=45+1。总的公式为highxdigit+low+1;

3)当cur>1时,以23345为例子,求百位上出现1的次数,此时可以把0-23345拆分成0-23199以及23200-23345。第二项23200-23345显然没有满足要求的数字。那么求0-23199中百位出现1次数可以由第二种情况得出:highxdigit+low+1=23x100+99+1。由于cur是>1的,所以所求的数字(23345)向下取到 满足要求的最大数字(23199)时,low位数字必然是99,而0~99个数正好是digit(100=99+1)。所以可以把22345转化为22199,此时公式为highxdigit+low+1 = highxdigit+digit=(high+1)xdigit。

由此看出,cur=1可以由cur=0演变过来,cur>1可以由cur=1演变过来
注意跳出循环条件,这里cur!=0是为了解决输入个位数字(1-9)的问题

代码

class Solution {
    public int countDigitOne(int n) {
        int low=0,cur=n%10,high=n/10,digit=1;
        int sum=0;
        while (high!=0 || cur!=0){
            if(cur==0) sum+=high*digit;
            else if(cur==1) sum+=high*digit+low+1;
            else sum+=(high+1)*digit;
            low+=cur*digit;
            cur=high%10;
            high/=10;
            digit*=10;
        }
        return sum;

    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

时间邮递员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值