lintcode--第3题:统计数字

描述:
计算数字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;
    }
};

猜你喜欢

转载自blog.csdn.net/zhudky/article/details/79047698