题目:1~n 整数中 1 出现的次数
思路:(参考力扣上Krahets大佬的题解以及ryan0414的解释):
可以参考密码锁 进而找规律
复杂度: 时间复杂度O(m) (m为n的位数) 空间复杂度 O(1)
'''
题目:1~n 整数中 1 出现的次数
思路(参考力扣上Krahets大佬的题解以及ryan0414的解释):
可以参考密码锁 如n=abcd 即有四位密码
① 我们求abcd出现1的可能可以分为 求每位出现1可能的累加
②当我们求b位上出现密码值为 1 的个数上时(我们记a=high cd=low) 只需要将b位置1 求其他位的可能组合即为子问题的解,此时分为以下几种情况
i 当 b 的值恰好为1 n = a1cd 此时求 000-acd的大小即可 acd-0+1 = high*100 + low + 1
ii 当 b 的值小于1 n = a0cd 如果b位置想出现1 a必须要降一位 而此时cd都可以取9 即此时求 000-(a-1)99的范围大小即可 (a-1)99 - 0 + 1 = a00 = high*100
iii 当 b 的值大于1 n = a2cd 如果b位置想出现1 cd可以取9 即此时求 000-a99的范围大小即可 a99-0+1 = (a+1)00 = (high+1)*100
③ 我们将4中可能累加
复杂度: 时间复杂度O(m) (m为n的位数) 空间复杂度 O(1)
'''
def countDigitOne(n):
n_str = str(n)
count = len(n_str)
value = 1
res = 0
for i in range(count):
# 使用字符来求high和low
high_str = n_str[:i]
if high_str == '':
high = 0
else:
high = int(high_str)
if i == count-1: # 注意此处的条件 当i取得最后一位时
low = 0
else:
low = int(n_str[i+1:])
# 三种情况讨论
if int(n_str[i]) == value:
res += high * pow(10, count-1-i) + low + 1
elif int(n_str[i]) < value:
res += high * pow(10, count-1-i)
else:
res += (high + 1) * pow(10, count-1-i)
return res