剑指offer 最快找出整数中1出现的次数

本文使用python实现


1. 问题

    求1~1300的整数中1出现的次数?比如1,10,11,12,13这5个数字中1出现了6次。
    
    时间限制:1s;空间限制:32768K

2 思路描述

方法一:暴力解法(当数字较小时可以,数字很大时不可取)
方法二:观察规律(在此我们将题目拓展成整数中 X 出现的次数, X∈{1,2,3,4,5,6,7,8,9} )
    (1)在 [1,10] 中 ,个位上 X 出现的次数为 1 。
    (2)在 [11,100] 中,十位上 X 出现的次数为 10 。
    (3)在 [101,1000] 中,百位上 X 出现的次数为 100 。
    (4)以此类推,在 [10i+1,10(i+1)] 上,从右数第 i 位上 X 出现的次数为 10(i−1) 。
    而 [1,n] 中第 i 位上 X 出现的次数规律为:
    (a)当第 i 位的数字 >X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i+1)∗10(i−1)
    (b)当第 i 位的数字 <X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i)∗10(i−1)
    (c)当第 i 位的数字 =X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i)∗10(i−1)+(n取模10i−1∗10(i−1)+1)
     注意:// 表示整除的意思。

  举例说明:
    对于 [1,2593] 中 5 出现的次数:
    (1)个位(从右至左第1位):由于个位 3<5 ,故对照规律(b):2593//101×10(1−0)=259 ,也就是说,在 [0 2593] 中 5 在个位上出现了 259 次。
    (2)十位(从右至左第2位):由于十位上的数字 9>5 ,故对照规律(a): (2593//102+1)×10(2−1)=260 ,也就是说,在 [0 2593] 中 5 在十位上出现了 260 次。
    (3)百位(从右至左第3位):由于百位上的数字 5=5 ,故对照规律(c): (2593//103)∗10(3−1)+(2593取模103−5∗10(3−1)+1)=294 ,也就是说,在 [0 2593] 中 5 在百位上出现了 294 次。
    (4)千位(从右至左第4位):由于百千位上的数字 2<5 ,故对照规律(b):(2593//104)×10(4−0)=0 ,也就是说,在 [0 2593] 中 5 在千位上出现了 0 次。
    故 5 在 [1,2593] 中共出现了 259+260+294+0=813 次。

3 程序代码:

class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        count = 0
        tmp = n
        i = 1
        while tmp != 0:
            # a为每位上的数字
            a = tmp % 10
            rem = n % (10**i)
            con = n // (10**i)
            base = 10**(i-1)
            if a > 1:
                count += (con + 1) * base
            elif a < 1:
                count += con * base
            else:
                count += con * base + (rem - 1*base + 1)
            tmp = tmp // 10
            i += 1
        return count
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值