《剑指offer》--- 整数中1出现的次数

本文算法使用python3实现


1. 问题

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


2 思路描述

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

  举例说明
    对于 $ [1,2593] $ 中 $ 5 $ 出现的次数:
    (1)个位(从右至左第1位):由于个位 $ 3<5 $ ,故对照规律(b):$ 2593//10^1 \times 10^{(1-0)} = 259 $ ,也就是说,在 $ [0~2593] $ 中 $ 5 $ 在个位上出现了 $ 259 $ 次。
    (2)十位(从右至左第2位):由于十位上的数字 $ 9>5 $ ,故对照规律(a): $ (2593//10^2+1) \times 10^{(2-1)}=260 $ ,也就是说,在 $ [0~2593] $ 中 $ 5 $ 在十位上出现了 $ 260 $ 次。
    (3)百位(从右至左第3位):由于百位上的数字 $ 5=5 $ ,故对照规律(c): $ (2593//10^3) * 10^{(3-1)} + (2593取模10^3-5*10^{(3-1)}+1) = 294 $ ,也就是说,在 $ [0~2593] $ 中 $ 5 $ 在百位上出现了 $ 294 $ 次。
    (4)千位(从右至左第4位):由于百千位上的数字 $ 2<5 $ ,故对照规律(b):$ (2593//10^4) \times 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

猜你喜欢

转载自www.cnblogs.com/lliuye/p/9205722.html
今日推荐