阶乘数字总和难题,时间复杂度调查

Factorial digits sum puzzle, time complexity survey

您认为 foo 函数的时间复杂度是多少(相对于 n)?

DIGIT_FACTORIAL = [1]
for x in range(1, 10):
    DIGIT_FACTORIAL.append(DIGIT_FACTORIAL[x-1]*x)

def digit_factorial(x):
    return DIGIT_FACTORIAL[x]

def foo(number_of_digits):
    n = 10**number_of_digits
    i = n//9

    while i != sum(digit_factorial(int(x)) for x in str(i)) and i < n:
        i += 1

    if i < n:
        return i
    return None 

O(n log(n))

解释:

每个 while 循环从 111...1 == n/9 运行到 n。这意味着 while 循环运行 n*8/9 次。 O(n * some_constant) == O(n).

在每次迭代中,总和是在 i 中的所有数字。 i 中有 log10(n) - 1 个数字。 O(log10(n) - 1) == O(log(n)).

将两者嵌套使得 O(n log(n)).

请注意,上面的解释没有考虑到如果 i == sum(...) 循环可能会提前中断。这是因为 sum(digit_factorial(int(x)) for x in str(i)) 的上限是 9! * number_of_digits,当 number_of_digits 大于 7 左右时,它总是小于 i