剑指offer30~60题(Python版本)

32.整数中1出现的次数(从1到n整数中1出现的次数)

问题:输入一个数字n,求从1到n这n个十进制整数中1出现的个数,例如输入12,则1-12中包含1个数字是1,10,11,12,所以1出现的次数是5。
算法思想:
算法思想:寻找规律,例如21345,

  1. 把数字分成两部分,1~1345和1346~21345
  2. 在第二部分中,1出现的情况分为两种,首先1出现在最高位,这里是万位,出现了10000次,(如果数字是12345的话,出现在在1高位的次数是1+2345=2346次,即取出最高位,剩下的加一);
    第二种情况,1出现出最高位之外的情况,例子中1346~21345中1出现的次数是2000次(最高位是2,我们把1346~21345分成两段:1346~11345和11346~21345,每一段剩下的四位数字中,选择其中一位是1,剩余的三位可以再0~9中任意选择,根据排列组合原则,总共出现的次数是2*10^3=2000次)
  3. 第一部分1出现的次数,可以递归求得
# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        # write code here
        if n<=0:
            return 0
        strDigit=str(n)    #将数字转化成字符串
        result=self.numberOf1(strDigit)
        return result
    def numberOf1(self,strDigit):
        if (not strDigit) or (strDigit[0]<'0')or(strDigit[0]>'9')or(strDigit[0]=='\0'):
            return 0
        firstDigit=int(strDigit[0])
        digitLen=len(strDigit)
        if digitLen==1 and firstDigit==0:
            return 0
        if digitLen==1 and firstDigit>0:
            return 1
        numFirstDigit=0
        if firstDigit>1:    #计算第一部分最高位数字是1个个数
            numFirstDigit=pow(10,digitLen-1)
        elif firstDigit==1:
            numFirstDigit=int(strDigit[1:])+1
        numOtherDigit=firstDigit*(digitLen-1)*pow(10,digitLen-2) #计算第一部分除了最高位的1的个数
        numRecursive=self.numberOf1(strDigit[1:])    #递归计算第二部分中1的个数
        return numFirstDigit+numOtherDigit+numRecursive

猜你喜欢

转载自blog.csdn.net/john_bh/article/details/79582914