描述:
计算数字k在0到n中的出现的次数,k可能是0~9的一个值
样例:
例如n=12,k=1,在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我们发现1出现了5次 (1, 10, 11, 12)
标签:
枚举法
求k出现的次数,可以等价为求k在各个数位上出现的次数之和。
假设n=5555,当前考虑十位,
- k< 5 : 假设k=4,则有(00~55)4(0~9),次数为(55+1)x10;
- k=5 : 假设k=5,则有(00~54)5(0~9),次数为55x10,以及5550~5555,次数为(5+1),共 55x10+5+1;
- k>5 : 假设k=6,则有(00~54)6(0~9),次数为55x10;
由于n的位数不确定,考虑从个位开始向高位计算。假设 n=abcd ,当前考虑位为m,可列处下表:
位数因子 | 前面的位 | 当前位 | 后面的位 | k < m | k=m | k>m |
---|---|---|---|---|---|---|
1 | abc | d | 0 | (abc+1)*1 | abc*1+0+1 | abc*1 |
10 | ab | c | d | (ab+1)*10 | ab*10+d+1 | ab*10 |
100 | a | b | cd | (a+1)*100 | a*100+cd+1 | a*100 |
1000 | 0 | a | bcd | (0+1)*1000 | 0*1000+bcd+1 | 0*1000 |
接下来考虑有无这个规律不适用的情况:
表中考虑了k在最高位是的情况,如举例n=5555时,计算次数考虑了k=0时,(0~0)0(000~999)的情况,然而0是不能做最高位的;
class Solution {
public:
/*
* @param : An integer
* @param : An integer
* @return: An integer denote the count of digit k in 1..n
*/
int digitCounts(int k, int n) {
// write your code here
int factor = 1;//位数因子
int kNumber = 0;//次数
//while循环的例外情况
if(n==0 && k==0){
return 1;
}
while(n/factor != 0){
int backBit = n%factor; //后面的位
int frontBit = n/(factor*10); //前面的位
int thisBit = n/factor - frontBit*10;//当前位
if(k==0 && frontBit==0){
break;
}
else if(k < thisBit){
kNumber += factor*(frontBit + 1) ;
}
else if(k == thisBit){
kNumber += factor*frontBit + backBit + 1;
}
else{
kNumber += factor*frontBit;
}
factor *= 10;
}
return kNumber;
}
};