LintCode 1312. 数字1的个数

1312. 数字1的个数

题目描述

给定整数n,计算出现在小于等于n的所有非负整数中的数字1的总数。

样例:
输入:13
输出:6

样例:
输入:100
输出:21

思路

  • 很容易想到的思路是采用暴力求解的方法,判断从1到N每个数中含有1的个数,然后将其相加,但这种方法的时间复杂度很高,不是很适用。

  • 找到其中的规律,用数学规律来求解这道题目。

    • 如样例中N = 13的情况来看:
      个位出现1的次数有2次:1、11
      十位出现1的次数有4次:10、11、12、13
      总共有6次。
    • 样例N = 123的情况来看:
      个位出现1的次数有13次:1、11、21、31、41、51、61、71、81、91、101、111、121.
      十位出现1的次数有20次:10~19、110 ~119.
      百位出现1的次数有24次:100~123.
      总共有57次。

规律如下:

求取当前位的高位,低位,位数,并和当前位结合起来。

  • 当前位 = 0,res += higher * factor;
  • 当前位 = 1,res += higher * factor + lower + 1;
  • 当前位 > 1,res += (higher + 1)*factor;

相关代码

int countDigitOne(int n) {
 // write your code here
    if (n <= 0) {
       return 0;
    }
    int res = 0;
    int factor = 1;
    int lower = 0;
    int cur = 0;
    int higher = 0;

    while ((n / factor )!= 0) {
       lower = n - (n / factor)*factor;
       cur = (n / factor) % 10;
       higher = n / (factor * 10);
 
       switch (cur) {
       case 0:
            res += higher * factor;
            break;
       case 1:
            res += higher * factor + lower + 1;
            break;
       default:
            res += (higher + 1)*factor;
            break;
       }
       factor *= 10;
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值