1~n整数中1出现的次数 -找规律

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。

暴力的方法是将每一个数都依次判断每一位上是否是1,然后相加,这样无法通过,时间超过限制。
可以考虑计算每一位可能出现1的总次数,然后把每一位相加。时间复杂度是nlgn。

其实是把每一位分开进行的计算。

下面的方法时间复杂度是lgn,一个while循环,n / (10**T) = 1, T = logn
其中遇到的问题:

  1. 乘方是**,而不是^, 这是异或的意思
  2. 5/2 = 2.5 , 5//2 = 2
  3. 是计算每一位上可能出现1的次数,只需要计算该位的,并且不会发生重叠,因为每次都只计算自己,题意是要计算各个位上所有的1的次数,而不是出现1的数字的次数之和。
  4. 下面的代码按大于1,小于1,和等于1来展开,三种情况,对应的某一位为1的次数是不同的。值得注意的是,如果该位是1,那么可以举例:21343,倒数第四位是1,此时,跟22343的区别是,22343多了21344-21999的次数,所以直接加上343+1(注意可以为0),为10 ** 3 * 2+343+1。如果是22343那么是10 ** 3 * 3。小于1的话,如20343,那么是10 ** 3 * 2,对比相等少去了后面的部分。
class Solution(object):
    def countDigitOne(self, n):
        # 分为大于1,小于1,等于1三种情况,分别计数每一位上的1可能出现的总数,再相加。
        if n < 0:
            return 
        def countone(n,x): # 倒数第x位
            cur = n // (10**(x-1))   # 该位的数值
            one = cur % 10
            prenum = n // (10**x)  # 前面的整数部分
            postnum = n % (10**(x-1)) # 后面的整数部分
            if one > 1:
                count = 10**(x-1)*(prenum+1) # 拆开比较麻烦,因为后面是9/99/999...
            elif one == 1 :
                count = 10**(x-1)*(prenum) + postnum + 1
            else:
                count = 10**(x-1)*(prenum)   # 也可以是 (prenum-1) * 10**(x-1) + postnum + 1
            return count

        copyn = n
        count = 0
        x = 1
        while copyn > 0:
            copyn = copyn // 10
            count += countone(n,x)
            x += 1
        return count

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值