2
p = 0
for( i=1; i<n; i=i*2 ) { 
    p++ // log n 
} 

for( j=1; j<p; j=j*2 ) { 
    some_statement // log P
}
//  O( log log n )

Why a variable coming from an independent loop affects another loop's time? And if we were to delete the second loop, time complexity would be just O(logn) which is more slower. Why the time complexity isn't just logn + logn = 2logn therefore O(logn)?

mark
  • 81
  • 7
  • 2
    The first loop isn't actually doing much work apart from calculating log n. And then the second loop is log p, not log n. So if you're interested in how many times `some_statement` will run, it will be log log n, but obviously this can be rewritten using a single loop. – vgru Sep 29 '22 at 21:33
  • 1
    You need to specify what time complexity are you talking about. There are `O(log(n))` increments, but `O(log(log(n))` executions of `some_statement`. Adding them together doesn't make sense, neither does comparing them (assuming `some_statement` is actually time consuming compared to `p++`). – Yksisarvinen Sep 29 '22 at 21:42

2 Answers2

2

Because they are not independent: The first computes p = O(log n) and the second depends on it. The time complexity of the second loop would be O(log p) = O(log log n).

However, the first loop is still O(log n), which indeed makes the time complexity of the entire program O(log n + log log n) = O(log n), as you say.

Berthur
  • 4,300
  • 2
  • 14
  • 28
  • Thanks for clarifying the end complexity, but the fact that I don't understand is that p is nothing but an integer; how can it make a loop run faster? Why is it any different than any other variable after it is defined and updated? Why its time complexity stays with it? – mark Sep 29 '22 at 21:51
  • 1
    @atacavusoglu Your confusion is that of naming, I think. Your second loop is logarithmic indeed, *O(log p)*. With no other code, we would leave it at that. It's not *O(log n)* because there is no *n* there, only *p*. However, we happen to know that *p = O(log n)*, so you can choose whether to express the second loop's complexity as *O(log p)* or *O(log log n)*, both are correct. – Berthur Sep 29 '22 at 21:59
  • 1
    @atacavusoglu It's like I tell you *z = 2x*, but also we know that *x = 2y*. I can them correctly state that *z = 4y*. – Berthur Sep 29 '22 at 22:01
2

By creating the second loop

for( j=1; j<p; j=j*2 ) { 
    some_statement // log P
}

You have added additional time complexity based on the input parameter n. After executing loop 1, we will have p = log2 n, meaning your second loop becomes

for( j=1; j< log2 n; j=j*2 ) { 
    some_statement // log2 (log2 n)
}

So the total time complexity of loop1 and loop2 = loop1 + loop2 = log2n + log2(log2(n)) which is O(logn)

Ryan
  • 154
  • 4