统计数字

计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值。

样例 1:

输入: k = 1, n = 1 输出: 1 解释: 在 [0, 1] 中,我们发现 1 出现了 1 次 (1)。

样例 2:

输入: k = 1, n = 12 输出: 5
解释: 在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12] 中,我们发现 1 出现了 5 次 (1, 10, 11, 12)。
11里面有2个1 所以是5次

解题思路
首先 得找规律 假设n是123
当k是1时
个位带1的是 1 ,11 ,21 ,31 ,41 ,51 ,61 ,71 ,81 ,91
101 ,111 ,121
个位带1的一共13个
十位带1的是 10,11,12 ,13 ,14 ,15 ,16 ,17, 18 ,19
110,111,112,113,114,115,116,117,118,119
十位带1的一共20个
百位带1的是 100,101,102,103,104,105,106,107,108,109
110,111,112,113,114,115,116,117,118,119
120,121,122,123
百位带1的一共24个
所以0~123里面1出现了57次
当k是2时
个位带2的是 2 ,12 ,22 ,32 ,42,52 ,62 ,72 ,82 ,92
102 ,112 ,122
个位带1的一共13个
十位带2的是 20,21,22 ,23 ,24 ,25 ,26 ,27, 28 ,29
120,121,122,123
十位带1的一共14个
百位带1的是 一个没有
所以0~123里面2出现了27次

总结下来 比如n为123
k为1时 个位1出现 (123 / 10) * 1 + 1 = 13
十位1出现 ((123 / 10 ) / 10) * 10 + 10 = 20
百位1出现 (123%100)+1 = 24
k为2时 个位2出现 (123 / 10) * 1 + 1 = 13
十位2出现 ((123 / 10)/10) * 10 + (123%10)+1 = 14

继续总结 当 n为12345
k为3 个位为5 5>3 (12345 / 10) * 1 +1 = 1235
十位为4 4>3 ((12345/10)/10) * 10 + 10 = 1240
百位为3 3=3 (((12345/10)/10)/10) * 100 + (12345%100)+1 = 1246
千位为2 2<3 ((((12345/10)/10)/10)/10) * 1000 +0 = 1000
万位为1 1<3 最高位小于1 所以最高位存在0个
加起来 存在3的次数为4721次
那我们找到了规律
上面加粗部分是 每位必须有的
然后后面是加 他的位数 还是加(n % 位数)+ 1
是取决于当前位数 大于k还是 等于k 还是小于 k
在上面 我们找到了当k是1到9时的规律 然后开始找 k是0的规律
当n为12345 k是0时
k为3 个位 (12345 / 10) * 1 +1 = 1235
十位 ((12345/10)/10) * 10 = 1230
百位 (((12345/10)/10)/10) * 100 = 1200
千位 ((((12345/10)/10)/10)/10) * 1000 +0 = 1000
万位 最高位存在0个
加起来 存在0的次数为4665次
所以当k是0时 除了 个位多加了1 其他为 都直接取 (n/当前位数/10) * 当前位数

代码如下

	public int digitCounts(int k, int n) {
      
        
        if(k==0&&n<10){
            return 1;
        }
        int m = n;
        int count = 0;
        int base = 1;
        while(m>0){
            int lastNum = m % 10;
            m = m/10;
            count = count + m*base;
            //k大于0的情况
            if(k>0){
                
                if(lastNum == k){
                    count = count + (n % base)+1;
                }else if(lastNum < k){
                    count = count + 0;
                }else{
                    count = count + base;
    
                }
            //k为0的情况
            }else{
                if(lastNum>k&&base==1){
                    count = count + 1;
                }
                
            }
            base = base * 10; 
        }
        return count;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值