整数中1出现的次数(从1到n整数中1出现的次数)

题目描述

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。

算法一:

暴力累加,从1到n,统计每个位置的1.

算法二:

利用数字规律,我们用一个数字特例21345做例子,来解释这个算法,我们设置辅助变量

i = 10;

j = 1;

(1)首先统计21345个位可能出现的1的次数,因为个位每10次出现1次,同时当个位为大于1的数的时候还出现1次

count = 21345 / i(10) * j (1)  + 1( 余数1 , 1 <= 1 < 2)

(2)其次统计21345十位可能出现的1的次数,因为每个100里边十位出现1次1,共10个,则

count = 21345 / i(100) * j (10)  + 10( 余数45 , 20 < 45)

(3)则百位可能出现1的次数

count = 21345 / i(1000) * j (100)  + 100( 余数345 , 200 < 345)

(4)则千位可能出现1的次数

count = 21345 / i(10000) * j (1000)  + (1345 - 1000 + 1)( 余数1345 , 1000 <= 1345 < 2000)

(5)则万位可能出现1的次数

count = 21345 / i(100000) * j (10000)  + 10000( 余数21345 , 20000 < 21345)

可以看出是有规律的,所以代码如下:

public int NumberOf1Between1AndN_Solution(int n) {
       int count = 0;
        int i = 10;
        int j = 1;
        while (i <= n * 10){
            count += n / i * j;
            int len = n % i;
            if (len >= 2 * j){
                count += j;
            }else if (len >= j){
                count += len - j + 1;
            }
            i *= 10;
            j *= 10;
        }
        return count;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值