0

I'm struggling to find the time complexity of this function:

void foo(int n) {
    int i, m = 1;
    for (i = 0; i < n; i++) {
        m *= n; // (m = n^n) ??
    }
    while (m > 1) {
        m /= 3;
    }
}

Well, the first for iteration is clearly O(n^n), the explanation to it is because m started with value 1, and multiplies itself n times.

Now, we start the while loop with m = n^n and we divide it every time by 3. which means, (I guess), log(n^n).

Assuming I got it right up till now, I'm not sure if I need to sum or multiply, but my logic says I need to sum them, because they are 'odd' to each other.

So my assumption is: O(n^n) + O(log(n^n)) = O(n^n) Because if n is quite big, we can just refrain from O(log(n^n)).

Well, I really made many assumptions here, and I hope that makes sense. I'd love to hear your opinions about the time complexity of this function.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Ilan Aizelman WS
  • 1,630
  • 2
  • 21
  • 44

2 Answers2

2

Theoretically, time complexity is O(n log n) because:

for (i=0; i<n; i++) 
   m *= n;

this will be executed n times and in the end m=n^n

Then this

while (m>1)
   m /= 3;

will be executed log3(n^n) times which is n * log3(n):

P.S. But this is only if you count number of operations. In real life it takes much more time to calculate n^n because the numbers become too big. Also your function will overflow when you will be multiplying such big numbers and most probably you will be bounded by the maximum number of int (in which case the complexity will be O(n))

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
0

With foo(int n) and 32-bit int, n cannot exceed the magnitude of 10, else m *= n overflows.

Given such a small range that n works, the O() seems moot. Even with 64-bit unsigned m, n <= 15.

So I suppose O(n lg(n)) is technically correct, but given the constraints of int, suspect code took more time to do a single printf() than iterate through foo(10). IOWs it is practically O(1).

unsigned long long foo(int n) {
  unsigned long long cnt = 0;
  int i;
  unsigned long long m = 1;
  for (i = 0; i < n; i++) {
    if (m >= ULLONG_MAX/n) exit(1);
    m *= n; // (m = n^n) ??
    cnt++;
  }
  while (m > 1) {
    m /= 3;
    cnt++;
  }
  return cnt;
}

And came up with

1 1
2 3
3 6
4 9
5 12
6 16
7 19
8 23
9 27
10 31
11 35
12 39
13 43
14 47
15 52
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256