Time Complexity : Continuously summing the digits

2019-07-10 00:16发布

I am given a number N. Keep summing the digits until a single digit result. e.g 35252 ==> 17 ==> 8 I have written the following code :

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;
}

Coming to the time complexity : I am given the range for N as 0 <= N <= 10^9.

In worst case, with all 9s, the recursion will go max twice and I will get O(loglogn)

In best case, with single digit N, complexity will be O(1)

What will be the average complexity? I mean, what will be the complexity if N can be any number with no range defined.

2条回答
女痞
2楼-- · 2019-07-10 00:36

Well known solution is n % 9 + (n % 9 == 0 ? 9 : 0).

查看更多
乱世女痞
3楼-- · 2019-07-10 01:03

First, your analysis is wrong, the time complexity is not O(loglogn) for worst case, it's O(logn), with the following recursive formula:

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

Now, we can show that the above is in O(logn), using induction with the induction hypothesis of: 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)

Showing it is Omega(log(n)) is pretty trivial, with the observation that T(n) >= 0 for all n.


Regarding the question at hand, what is the average time complexity, let's denote the average case complexity with G(n), and let's assume n is uniformly distributed (if it's not - that will change the analysis, and the outcome might be different).

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

So, we can conclude G(N) is also in O(logN), so the average case analysis is still logarithmic in N.

查看更多
登录 后发表回答