algorithm - 时间复杂度: Continuously summing the digits of a number until a single digit result

标签 algorithm time-complexity

给我一​​个数字 N。不断对数字求和,直到结果为一位数。 例如 35252 ==> 17 ==> 8 我编写了以下代码:

int digitSum(int n)
{
    int sum = 0;
    int digit;

    while(n)
    {
        digit = n%10;
        n = n/10;
        sum += digit;
    }

    if(sum > 9)
        return digitSum(sum);
    else
        return sum;
}

时间复杂度: N 的范围为 0 <= N <= 10^9。

在最坏的情况下,全部都是 9,递归将达到最大值两次,我将得到 O(loglogn)

在最好的情况下,对于个位数 N,复杂度将为 O(1)

平均复杂度是多少?我的意思是,如果 N 可以是任何没有定义范围的数字,那么复杂度是多少。

最佳答案

首先,你的分析是错误的,最坏情况下时间复杂度不是O(loglogn),而是O(logn) ,具有以下递归公式:

T(n) = logn + T(log(n) * AVG(digits)) = logn + T(9*logn)
T(1) = 1

现在,我们可以证明上面的内容在 O(logn) 中,使用归纳法,归纳假设为:T(n) <= 2logn

T(n+1) = log(n+1) + T(9logn) <= (i.h) log(n+1) + 2*log(9log(n)) =
       = log(n+1) + 2log(9) + 2loglog(n) < 2log(n)

显示的是Omega(log(n))是相当微不足道的,观察 T(n) >= 0对于所有人n .


关于手头的问题,平均时间复杂度是多少,让我们用G(n)来表示平均情况复杂度。 ,我们假设 n是均匀分布的(如果不是 - 这将改变分析,结果可能会不同)。

G(N) = lim{N->infinity} sum{i=1 to N} T(n)/N =
     = lim{N->infinity} T(1) / N + T(2) / N + ... + T(N) / N
     = lim{N->infinity} 1/N (T(1) + T(2) + ... + T(N))
     < lim{N->infinity} 1/N (2log(1) + 2log(2) + ... + 2log(N)) 
     = lim{N->inifnity} 2/N (log(1) + ... + log(N))
     = lim{N->inifnity} 2/N (log(1 * 2 * ... * N))
     = lim{N->infinity} 2/N log(N!) 
     = lim{N->infinity} 2/N * CONST * NlogN = 2*CONST * logN

所以,我们可以得出结论G(N)也在 O(logN) ,因此平均案例分析在 N 中仍然是对数的.

关于algorithm - 时间复杂度: Continuously summing the digits of a number until a single digit result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41073179/

相关文章:

java - 估算java程序在程序结束前的执行时间

python - 查找树形图算法代码/伪代码时遇到麻烦

algorithm - 两个数相除的时间复杂度是多少?

algorithm - 从整数流创建最大堆

java - Boyer-Moore 或 Java 或 Scala 库中的类似库

C++编程除法算法

python - 需要帮忙!使用 python 计数素数

java - for循环内while循环的时间复杂度

algorithm - 来自一组区间的第 K 个最小值

algorithm - O(n log n) vs O(n)——时间复杂度的实际差异