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 种情况;
- 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;
}
};