昨天子序列的原创审核居然没有通过,无语子
不应该放ppt截图的。
今天的leetcode居然是一个困难题,加油!
上次也做出来啦。
链接: https://leetcode-cn.com/problems/number-of-digit-one/
给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
示例 1:
输入:n = 13
输出:6
示例 2:
输入:n = 0
输出:0
提示:
思路:
用递推思想,数字范围那么大,肯定是要找规律的。
(1) n < 10 的时候 return 1.
(2)n == 10 return 2
(3)n == 11 return 4
(4)n== 12 -- 19 return 4 + n - 11 --> 4 + 8
(5)n == 20 -- 99 return moddiv(n,10) == quotient,remainder
return 4+ 8 + (quotient-2) + remainder > 0
然后发现了一个这个规律:
99 = 2 * 10
999 = 100 + 10 * 20
9999 = 1000 + ( 100 + 10 * 20 ) * 10
99999 = 10000 + (1000 + 300 * 10) * 10
那可以怎么说呢?
先判断什么数字范围。 100 以下的单独计算,100以上的走规律。
最大也就 2 * 10 ^9 次方,可以先先写个 10^ 9 -1 的映射字典:
是个没什么意思的题
但是我也想做出来
class Solution:
def countDigitOne(self, n: int) -> int:
# 0 -99 的映射字典
def get_one(n):
res = 0
quotient,reminder = divmod(n,10)
if quotient < 1:
if reminder < 1:
res = 0
else:
res = 1
elif quotient == 1:
if reminder < 1:
res = 2
elif reminder == 1:
res = 4
else:
res = 4 + reminder - 1
else:
res = 4 + 8 + quotient - 2
if reminder > 0:
res += 1
return res
res_dict = {99:20}
tmp_value = 20
for i in range(3,10):
tmp = 10 ** i - 1
res_dict[tmp] = 10 ** (i-1) + tmp_value * 10
tmp_value = res_dict[tmp]
if n < 100:
return get_one(n)
# 大于100的判断位数,然后加
str_n = str(n)
len_num = len(str_n)
# 按位数计算
# 前面的积累:
res = 0
while n >= 100:
quotient,reminder = divmod(n,10**(len_num-1))
if quotient == 1:
res += res_dict[10 ** (len_num-1)-1]
res += (reminder + 1)
else:
res += 10**(len_num-1)
res += (quotient) * res_dict[10 ** (len_num-1)-1]
n = reminder
len_num -= 1
res += get_one(n)
return res