(python version) 剑指 offer 43. 1~N 整数中1出现的次数

題目描述

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。

例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。

来源:力扣(LeetCode)

解題思路

  • 参考剑指 book 当中的举例方法。
  • 透过实例 21345 当做例子,分成最高位>1 以及 最高位=1 两种情况:
    • 如果最高位大于1的话,则有完整的 1 * (总位数-1) 个1,最高位是2,因此 total 有 1X10000 个 1; 但如果最高位是1的话,只有后一位数以后的个数 e.g. 12345,最高位是1,只有2345个1

    • 接著处理最高位后一位的 1 的个数,由于最高位有1与2两种选择 => 2; 1346~21345 当中后四位是1的排列组合:四位数当中,随机一个位置是1 => C4取1 ; 剩下三个位子当中从 0~9任选 => 10**3

    • 接著处理最高位后一位(第二位, 第三位…etc)的排列组合

Python 代碼

class Solution:
    def countDigitOne(self, n: int) -> int:
        if not n or n <1:
            return 0
        s = str(n)
        length = len(s)
        first_num = int(s[0])
        if length == 1:
            return 1
        
        # 如21345
        # 最高位(万位)出现1的次数:10000-19999的10000次
        # 最高位如果是1, 不滿10000次的情況
        if first_num >1:
            num_high = 10 ** (length-1)
        else:
            num_high = int(s[1:])+1

        # 1346-21345中,除最高位后(后四位中)出现1的总次数:最高位有1和2的选择,其余四位中包含1的排列組合為:(C4取1 * 10**3)=> 其餘3位從0-9數字當中任選,排列組合為10**3
        num_sub = first_num * (length-1)* 10**(length-1-1)
        return num_high + num_sub + self.countDigitOne(int(s[1:]))

你可能感兴趣的:((python version) 剑指 offer 43. 1~N 整数中1出现的次数)