剑指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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值