32.整数中1出现的次数(从1到n整数中1出现的次数)
问题:输入一个数字n,求从1到n这n个十进制整数中1出现的个数,例如输入12,则1-12中包含1个数字是1,10,11,12,所以1出现的次数是5。
算法思想:
算法思想:寻找规律,例如21345,
- 把数字分成两部分,1~1345和1346~21345
- 在第二部分中,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次) - 第一部分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