Digit Counts

Description



Count the number of k's between 0 and nk can be 0 - 9.


Example



if n = 12, k = 1 in

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

we have FIVE 1's (1, 10, 11, 12)

==========================          华丽分割线          ==========================


实现思路:

        介于遍历 0 ~ n,统计每个数字中 k 出现的次数思路处理有些低效,所以就不作实现。

        按位求解,依次求出个位,十位,百位,千位 ......可能出现 k 的次数,求和。


分析:

        (举个简单栗子  n = 222, k = 1 或 2 或 3

        个位

                个位数字就是 n % 10 = 2;

                (假设:n = 222, k = 1)   n % 10 > k

                那么个位出现 1 的所有情况就是: 001,011,021,... ...,091 ;101,111,... ...,191;201,211;221;

                总共就是 10 + 10 + 2 + 1。 即  (n / 10 + 1 )x 1 ( 个位数 )

                 ( 假设:n = 222, k = 2 )    n % 10 == k

                那么个位出现 2 的所有情况就是:002,012,022,... ...,092;102,112,... ...,192;202,212;222;

                总共就是 10 + 10 + 2 + 1。 即  (n / 10 )x 1  ( 个位数 ) + 1

                ( 假设:n = 222, k = 3 )    n % 10 < k

                那么个位出现 3 的所有情况就是:003,013,023,... ...,093;103,113,... ...,193;203,213;

                总共就是 10 + 10 + 2。       即  n / 10 )x 1  ( 个位数 )  

        十位:

                十位数字就是  n / 10 % 10 = 2;

                (假设:n = 222, k = 1)   n / 10 % 10 > k

                那么十位出现 1 的所有情况就是:010,011,012,... ...,019;110,111,... ...,119;210,211,... ...,219;

                总共就是 10 + 10 + 10 。即  (n / 10 / 10 + 1 ) x 10 ( 十位数 )

                (假设:n = 222, k = 2)   n / 10 % 10 == k

                那么十位出现 2 的所有情况就是:020,021,022,... ...,029;120,121,... ...,129;220,221,222;

                总共就是 10 + 10 + 2 + 1 。即  (n / 10 / 10 ) x 10 ( 十位数 ) + 2 + 1

                (假设:n = 222, k = 3)   n / 10 % 10 < k

                那么十位出现 3 的所有情况就是:030,031,032,... ...,039;130,131,... ...,139;

                总共就是 10 + 10。即  (n / 10 / 10 ) x 10 ( 十位数 )

        位:

                百位数字就是  n / 10 / 10 % 10 = 2;

                (假设:n = 222, k = 1)   n / 10 / 10 % 10 > k

                那么百位出现 1 的所有情况就是:100,101,102,... ...,199;

                总共就是 100 。即  (n / 10 / 10 / 10 + 1 ) x 100 ( 百位数 )

                (假设:n = 222, k = 2)   n / 10 / 10 % 10 == k

                 那么百位出现 2 的所有情况就是:200,201,202,... ...,222;

                总共就是 22 + 1。即 (n / 10 / 10 / 10 ) x 100 ( 百位数 ) + ( 1 x 22 ) + 1

                (假设:n = 222, k = 3)   n / 10 / 10 % 10 < k
                那么百位出现 3 的所有情况就是:;

                总共就是 0。即 (n / 10 / 10 / 10 ) x 100 ( 百位数 )

        注:有千位,万位,百万位等等依此类推


总结通用计算方式:

        引入变量  ( ulBitWeight ) 位权

                        (

                          当计算位置在个位时, ulBitWeight = 10 ^ 0

                          当计算位置在十位时, ulBitWeight = 10 ^ 1

                          当计算位置在百位时, ulBitWeight = 10 ^ 2

                          .... .... 

                        )

        if( n / ulBitWeight % 10 > k )

            k 在当前位所出现的总共次数为:( n / ulBitWeight  / 10 + 1 ) * ulBitWeight 

        if( n ulBitWeight % 10 == k )

            k 在当前位所出现的总共次数为:( n / ulBitWeight  / 10 ) * ulBitWeight + n % ulBitWeight  + 1

        if( n ulBitWeight % 10 < k )

            k 在当前位所出现的总共次数为:( n / ulBitWeight  / 10 ) * ulBitWeight 


        k 出现的次数就是各位置出现次数之和。

        *  处理两个特殊情况  *

        1、如果 k == 0, k 出现的次数 = n / 10 + 1;

        2、如果 k != 0, n == 0,k 出现的次数 = 0;


代码:

int digitCounts(int k, int n) {
        // write your code here
        int ulSum = 0; // k 出现的次数
        int ulBitWeight = 0; // 位权,个位为 10^0, 十位为,10^1, 百位为 10^2, 千位为 10^3 ... ... 依此类推
        
        // 特殊情况处理 k == 0, n == 0 
        if( k == 0 )
        {
            return n / 10 + 1;
        }
        else if( n == 0 )
        {
            return 0;
        }
     
        while( n > ulBitWeight )
        {
            // 位权处理,不使用 float 库函数 pow
            if( ulBitWeight == 0 )
            {
                ulBitWeight = 1; // 巧妙处理,利用初始值特殊处理个位 位权
            }
            else
            {
                ulBitWeight *= 10; // 其它位权处理
            }
            
            if( n / ulBitWeight % 10 > k )
            {
                ulSum += ( n / ulBitWeight / 10 + 1 ) * ulBitWeight;
            }
            else if( n / ulBitWeight % 10 == k )
            {
                ulSum += ( n / ulBitWeight / 10 ) * ulBitWeight + n % ulBitWeight + 1;
            }
            else if( n / ulBitWeight % 10 < k )
            {
                ulSum += ( n / ulBitWeight / 10 ) * ulBitWeight;
            }
        }
     
        return ulSum;
    }





猜你喜欢

转载自blog.csdn.net/u013393704/article/details/80514365