中:统计数字区间1出现的次数

题目描述

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

解:

这道题我们首先可以大概猜测出,1出现的次数跟位数有关。如果用位数直接对应有些麻烦,比如十位上的n(>1),会出现n+9次,但是n为百位,千位......上时规律比较难以求出,所以我们不采用这种方法。

我们可以把每个数位拆出来,比如十位,比如215,就会有11,12......19;111,112......119;211,212......215;可以看出这是由十位之前的数值所影响的,十位前面是2,所以十位上至少会有2*10次1的出现,本位和后位影响,5导致了5+1次的出现。显然百位同理,对于百位前的值为0,所以只剩本位,2,显然1已经过去了,所以从100......199共100个1存在。到这里我们可以推出规律,当current位的高位不为零时,本位一定至少会出现(高位*本位值),本位为0无影响,本位为1则有额外的(低位值+1)(因为0),本位为>1则直接(+本位值)。

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int cur=1;
        //n原值还有用,所以用个t来迭代
        int t=n;
        int yu;
        int sum=0;
        while(t!=0){
            yu=t%10;
            //高位,也是下一轮需要的值
            t/=10;
            sum+=(t*cur);
            if(yu==1){
                sum+=(n%cur+1);
            }
            if(yu>1){
                sum+=cur;
            }
            cur*=10;
        }
        return sum;
    }
}

当然,还有一种最直接的方法,就是暴力求解,把n递减,然后转换成数组来计算每一个值的1个数...缺点是特别慢...

--end--

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值