def count_nines(n):
x = list(map(str,range(n + 1)))
count = 0
for i in x:
c = i.count('9')
count += c
return count
执行超时(12000毫秒)
我该如何优化这段代码?
def count_nines(n):
if n==0:
return 0
k = len(str(n))-1
leading_digit, remainder = divmod(n, 10**k) # Thanks @Stef for this optimization
# Number of nines in numbers from 1 to leading_digit * 10**k - 1
count1 = leading_digit * k*10**(k-1)
# If the leading_digit is 9, number of times it appears
# (in numbers from 9 * 10**k to n)
count2 = remainder+1 if leading_digit==9 else 0
# Number of nines in remainder
count3 = count_nines(remainder)
# Total number of nines
return int(count1 + count2 + count3)
解释
首先,1-10^k 中数字 9 的数量(以下简称 c9())为 k * 10^(k-1)。这很容易通过递归证明,但我将以一个例子来说明: 假设 c9(1000) = 300,则数字 0xxx、1xxx…9xxx 的 xxx 部分中数字 9 的数量等于 10 * 300;加上 9000 到 9999 中的 9 的数量为 1000(共 1000 个九),因此得到 c9(10000) = 10*300 + 1000 = 4000。
现在假设你想知道 c9(7935):你有 7 * 300 个数字 9 在 1-7000 中,然后是 7 000 到 7 900 中的 9 * 20 个数字 9,接着是数字 900 到 935 中的 36 个前导数字 9,然后...
例子
count_nines(9254287593789050756)
Out[12]: 16880680640899572416
return int(leading_digit*k*10**(k-1) + (remainder+1 if leading_digit==9 else 0) + count_nines(remainder))
替换为 self_explaining_name1 = leading_digit*k*10**(k-1); self_explaining_name2 = remainder+1 if leading_digit==9 else 0; self_explaining_name3 = count_nines(remainder); return self_explaining_name1 + self_explaining_name2 + self_explaining_name3
。 - Stefint( ... )
,它们不已经是整型了吗? - Stefint
,它返回xxx.0。 - Swifty
for i in range(n):
然后将此“i”转换为字符串。然后你可能想采用另一种方法。作为人类,您如何检查1到99之间有多少个九?您真的需要检查11、12、13等吗?还是可以想出更有效的方法? - Sembei Norimakimap
对象(for i in map(str,range(n + 1))
),这样你就不会生成一个大的字符串列表,而是逐个处理每个值。 - Yevhen Kuzmovych