zoukankan      html  css  js  c++  java
  • 《剑指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 brace $ )
        (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 imes 10^{(1-0)} = 259 $ ,也就是说,在 $ [0~2593] $ 中 $ 5 $ 在个位上出现了 $ 259 $ 次。
        (2)十位(从右至左第2位):由于十位上的数字 $ 9>5 $ ,故对照规律(a): $ (2593//10^2+1) imes 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) imes 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
    
    
  • 相关阅读:
    django include
    @RequestParam 传值乱码问题
    View Merge 在安全控制上的变化,是 BUG 还是增强 ?
    postMessage实现跨域iframe自适应
    java.lang.IllegalStateException: Service id not legal hostname
    【以前的空间】 单调队列系列
    【以前的空间】 单调队列系列
    【以前的空间】 单调队列系列
    JAVA线程池shutdown和shutdownNow的区别
    JAVA线程池shutdown和shutdownNow的区别
  • 原文地址:https://www.cnblogs.com/lliuye/p/9205722.html
Copyright © 2011-2022 走看看