233. Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

Example:

Input: 13
Output: 6 
Explanation: Digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
    /*
    从LeetCode看到的答案,很容易理解
    原链接 https://leetcode.com/problems/number-of-digit-one/discuss/277541/1

    对于数字 abcde   (a,b,c,d,e 分别为数字的 万,千,百,十,个 位) 如 23456
    从1到abcde,数字1的位 出现的次数为:  个位出现1的次数 + 十位出现1的次数 + 百位出现1的次数 + 千位出现1的次数 万位出现1的次数

    以百分位为例求解(个,十,千,万位 也都是一样的)
    将abcde 看作 ab c de (a为万分位,b为千分位,c为百分位,d为十分位,e为个分位)。  左半边为ab ,右半边为cd
    1到abcde这些数可以分为两个部分:  从1到ab000(不包括ab000)    ab000到abcde

    从1到ab000(不包括abc00)中, 百分位为1,即c=1出现的次数为:
    (00) 1 [00、01、02……99]
    (01) 1 [00、01、02……99],
    (02) 1 [00、01、02……99]
    ……
    (ab-1) 1 [00、01、02……99]
    共ab*100次

    在ab000到abcde中,百分位为1,即c=1出现的次数为:
        if c>1,那么有 (ab)1[00,01,..99] 共100次
        if c==1,那么有 (ab)1[00,01,..de] 共de+1次
        if c==0,那么没有,为0次

    即,从1到abcde中的数,百分位为1的个数为
                ab*100 + 0         if c==0
                ab*100 + (de+1)    if c==1
                ab*100 + 100       if c>0

     因此,类推,我们可知:
     对于任意分位, 从1到n, 该分位为1的个数为
            左半边 * 该分位对应base  +  0
            左半边 * 该分位对应base  + (右半边+1)
            左半边 * 该分位对应base  +  该分位对应base
     左半边指的是 该分位左边组成的数(如上文的例子abcde,百分位,左半边为ab)
     右半边指的是 该分位右边组成的数(如上文的例子abcde,百分位,右半边为de)
     个分位对应base为1,  十分位对应base为10  ,   百分位对应base为 100 ,  千分位对应base为 1000
     */


    public int NumberOf1Between1AndN_Solution(int n) {
        int count=0;
        int base=1;//分位对应base(个分位对应1)
        int rightPart=0;//该分位右半部分(个分位右边为0)

        while(n>0){
            int leftPart = n/10;//左半部分
            count += leftPart*base;//左半部分*base
            int curr = n%10;// n的当前分位
            if(curr>1)
                count += base;
            else if(curr==1){
                count += rightPart+1;
            }

            n /= 10;
            rightPart += curr*base;//更新rightPart
            base *= 10;//更新base
        }
        return count;
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值