剑指offer-面试题43:1到n整数中1出现的次数

题目描述

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
示例 1:
输入:n = 12
输出:5
示例 2:
输入:n = 13
输出:6
限制:
1 <= n < 2^31

方法一(按位统计)

1.解题思路
  • 可以通过计算每一位为1时有多少种情况(比如个、十、百、千、万),然后把各个位上的情况做一个累加。
  • 举例说明:比如1102这个数字,个位为1的情况有(0001,0011,0021,……,1101)共(110+1)*1种,十位为1的情况有(0010,0011,0012,……0019,0110,0111,0112,……0119,1010,1011,1012,……1019)共11*10种,百位为1的情况有(0100,0101,……0199,……1100,1101,1102)共1*100+2+1种,同理千位为1的有102+1种
  • 总结:对于1102这个数,在确定某一位后,把它分为high、cur、low三部分,比如确定为个位的时候,high=110,cur=2,low=0。再代入之前总结的规律,当前位为1的总共有(high+1)*i种;同理,当前位等于0的时候,有high*i种,当前位等于1时,有high*i+low+1种。
2.代码实现
class Solution {
    public int countDigitOne(int n) {
        int res=0;
        //i是对应的位数,(比如个,十,百,千,万)
        for(long i=1;i<=n;i*=10){
            long low=n%i;
            long cur=(n/i)%10;
            long high=(n/i)/10;
            if(cur==0){
                res+=high*i;
            }
            else if(cur==1){
                res+=high*i+low+1;
            }
            else{
                res+=(high+1)*i;
            }
        }
        return res;
    }
}
3.复杂度分析
  • 时间复杂度:循环内的计算操作需要O(1)时间,循环的次数为n中数字个数,即log10n,所以时间复杂度是O(log10n)。
  • 空间复杂度:需要额外常数级别的空间,所以空间复杂度为O(1)。

方法二(情况合并)

1.解题思路

注意到当前位大于1时,与其他情况相比,高位系数要加1,所以可以通过加8除10的方式合并所有的情况。

2.代码实现
class Solution {
    public int countDigitOne(int n) {
        int count=0;
        for(long i=1;i<=n;i*=10){
           long a=n/i;     //当前位+高位组成的数
           long b=n%i;     //低位数字
           count+=(a+8)/10*i+(a%10==1?b+1:0);
        }
        return count;
    }
}
3.复杂度分析
  • 时间复杂度:循环内的计算操作需要O(1)时间,循环的次数为n中数字个数,即log10n,所以时间复杂度是O(log10n)。
  • 空间复杂度:需要额外常数级别的空间,所以空间复杂度为O(1)。

剑指offer全集入口: 请戳这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值