剑指offer31: 整数中1出现的次数(从1到n整数中1出现的次数)

题目:

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

思路1:(37ms)

从前向后一个一个的判断,累加

代码:

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int num = 0;
        if(n == 0){
            return 0;
        }
        if(n / 10 == 0){
            return 1;
        }
        for(int i = 1; i <= n; i++){            
            int temp = i;
            while(temp > 0){
                int b = temp % 10;
                if(b == 1){
                    num++;
                }                
                temp = temp / 10;
            }            
        }
        return num;    
    }
}

思路二:(15ms)

以214,为例:

个位上从0到9变化的次数,是21次,个位上1的总次数就是21加上最后一次(214%10是4,大于1,最后加1),21+1=22;

十位上从0到9变化的次数,是2次,十位上1的总次数就是2*10(十位上是1,说明连着10个数十位上都是1,所以乘10)加上最后4+1次(因为十位上是1,所以除了0到9变化的2次外,剩余的十位上1的次数取决于个位,当前例子就是210,211,212,213,214,5个,也就是个位数+1,);

百位上从0到9变化的次数,是0次,百位上的总次数就是0*100加上最后100次(234%1000=234,大于100,最后加100次)。

所以最后的表达式就是,n/Math.pow(10,i)+temp

其中,temp的取值有3中情况,n%(Math.pow(10,i)) == 0时,temp = 0(余数是0);

n%(Math.pow(10,i)) / Math.pow(10,i-1) == 1时,取决于前一位,比如十位是1,它的temp取决于个位,temp = n%(Math.pow(10,i)) - Math.pow(10,i-1) +1;

最后一种情况就是当前位不是1也不是0,如上例中的个位和百位的计算方式,temp = Math.pow(10,i-1)

代码:

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        if(n == 1 || n == 0){
            return n;
        }
        if(n / 10 == 0){
            return 1;
        }
        int num = 0;
        int a = n / 10;
        int b = n % 10;
        int temp = 0;//最后加的数
        int i = 1;
        int len = 0;
        int t = n;
        while(t != 0){
            t= t /10;
            len++;
        }
        while( i <= len){
            if(b == 0){
                temp = 0;
            }
            else if((int)(b / Math.pow(10,i-1)) == 1){
                temp =(int)(b - Math.pow(10,i-1)+1);
            }else{
                temp = (int)(Math.pow(10,i-1));
            }
            num += a * Math.pow(10,i-1) + temp;
            i++;
            a = (int)(n / Math.pow(10, i));
            b = (int)(n % Math.pow(10, i));
        }
        return num;
    }
}

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值