我需要确定一个最小的数制,在这个数制中,输入n(以10为基数)的数字都是1。
例:以2为底的7等于111 - fits!答案是2
21 in base 2 is 10101 - contains 0, does not fit
21 in base 3 is 210 - contains 0 and 2, does not fit
21 in base 4 is 111 - contains only 1 it fits! answer is 4
n is always less than Number.MAX_SAFE_INTEGER or equivalent.
我有下面的代码,它可以很好地处理一定范围内的数字,但对于巨大的数字,算法仍然很耗时:
def check_digits(number, base):
res = 1
while res == 1 and number:
res *= number % base
number //= base
return res
def get_min_base(number):
for i in range(2, int(number ** 0.5) + 2):
if check_digits(number, i) == 1:
return i
return number - 1
如何优化当前代码以使其运行得更快?
2条答案
按热度按时间6rqinv9w1#
以
b
为底的x
1字符串表示的数字是b^(x-1) + b^(x-2) + ... + b^2 + b + 1
。请注意,对于
x >= 3
,此数字大于b^(x-1)
(一般)且小于(b+1)^(x-1)
(应用二项式定理)。因此,如果一个数n
用x
1 s表示,以b
为底,我们有b^(x-1) < n < (b+1)^(x-1)
。应用x-1次根,我们有b < n^(1/(x-1)) < b+1
。因此,要使b
存在,b
必须是floor(n^(1/(x-1))
。到目前为止,我一直使用
^
表示法而不是Python风格的**
语法,因为这些等式和不等式只适用于精确的真实的运算,而不适用于浮点运算。如果您尝试使用浮点运算来计算b
,舍入误差可能会打乱您的计算。特别是对于ULP大于1的超大输入。(我 * 认为 * 浮点适合您使用的输入范围,但我不确定。)尽管如此,不管浮点数是否足够好,或者您是否需要更花哨的东西,算法的思想都在那里:可以通过直接计算对应的
b
必须是什么,并检查基b
中的x
1是否真正表示n
,来直接检查x
的值是否可行。6yt4nkrj2#
只是一些小的转折,稍微快一点,但没有提高时间复杂度。
也尝试一些数学技巧的方法,但我实际上使它更糟,哈哈