Leetcode Number of Digit One

本文介绍了一种算法,用于计算非负整数中小于等于给定整数n的所有数中数字1出现的总次数。通过分解数字并利用数学方法进行高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

我们假设给定的数字n=abcde。由于11算作1出现了2次,所以我们只要分别求出每个数位上出现1有几种情况就可以了,例如,假如n=12345,我们现在来求一下百位上出现1共有几种情况。我们设置lowerNumber=45,higherNumber=12,currentNumber=3,lowerCount=10^2-1(因为低位数字是2位数)。因为现在百位上的数字为3,3>1,所以higherNumber*10+1<higheNumber*10+currentNumber。 所以高位可以取到0~higherNumber,共higherNumber+1种可能,低位位可以取0~99(即10^2-1)共lowerCount种可能,所以在这种情况下,百位为1的情况有(higherNumber+1)*lowerCount种。

上面讨论的是currentNumber>1的情况。我们可以得出结论:

  • currentNumber>1的时候; 不超过给定n   且   该数位取1 有    (higherNumber+1)*lowerCount种情况;

在cunrrentNumber=0,以及CurrentNumber=1的时候,按照相同的方法讨论即可

当currentNumber==0的时候,由于高位等于higherNumber的时候是取不到1的,因此,高位可以取值的范围为:0~higherNumber-1,而低位的取值范围依然是0~lowerCount-1中,即:

  • currenNumber==0;不超过给定  n   且   该数位取1 有   (highNumber)*lowerCount 种情况;
当currenNumber==1的时候,高位分情况讨论,当高位为higherNumber的时候,低位部分只能取0~lowerNumber,当高位部分取0~higherNumber-1的时候,低位部分可以取得0~lowerCount-1.即:
  • currentNumber=1; 不超过给定  n  且该数位取1 有 (lowerNumber+1)+(higherNumber*lowerCount)种可能的情况;
class Solution {
public:
    int countDigitOne(int n) {
        int lown(0),lowc(1);
        int curn,highn(n);
        int res=0;
        while(highn>0){
            curn=highn%10;
            highn=highn/10;
            if(curn==0){//higher:0~highn-1,lower:0~lowc-1
                res+=highn*lowc;
            }
            if(curn==1){//higher:0~highn-1,lower:0~lowC-1
                res+=highn*lowc;
                //higher:hignn,lower:0~lown;
                res+=lown+1;
            }
            if(curn>1){//higher:0~highn,lower:0~lowc-1;
                res+=(highn+1)*lowc;
            }
            //update lowc, lown
            lown=curn*lowc+lown;
            lowc*=10;
        }
     
        return res;   
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值