2

Edit- this question is from a former test in my course, the official answer is O(n)

I need help understanding why does the run-time complexity in the following code is O(n) and not O(n*log(n))

def fun(n):
   total = 0
   while n > 5:
       n = n // 2
       total += sum(range(n))
   return total

The while loop executes log(n) times, and in each iteration the sum function sums n/2 numbers, therefore it's complexity is o(n), I see that each while iteration there's less numbers to sum, but i don't understand why it's O(n).

Thank you.

MadaBit
  • 145
  • 7
  • 2
    As written, it is `O(n log n)`, I think, but if you were to substitute the closed form `n * (n - 1) / 2` for `sum(range(n))` then it would go down to `O(log n)`, for the reason you mention. Maybe the person who's telling you it's `O(n)` is misunderstanding the while loop as being linear? – Green Cloak Guy Jan 07 '22 at 16:03
  • 3
    For what it's worth technically `sum(range(n))` can be computed in `O(1)` since it has a closed form solution. – Cory Kramer Jan 07 '22 at 16:04
  • @CoryKramer does python computes it that way? – MadaBit Jan 07 '22 at 16:09
  • 2
    This is a dupe of many questions, but the answer is because n + n/2 + n/4 + n/8 + ... is less than 2n. – Paul Hankin Jan 07 '22 at 16:09
  • 1
    It's essentially a dupe of https://stackoverflow.com/questions/29761284/why-is-this-algorithm-on/29761325#29761325 although that code is in C and stops when n is 0 rather than 5. – Paul Hankin Jan 07 '22 at 16:14
  • @MadaBit `range(n)` returns a range object which exposes properties for start, stop, step ... so you could write your own sum implementation to take advantage of that - AFAICT builtin `sum` does not though https://github.com/python/cpython/blob/main/Python/bltinmodule.c#L2421 – Anentropic Jan 07 '22 at 16:23

1 Answers1

0

So I've figured it out.

Each while iteration sums n/2 items. which means total iterations are n\2 + n\4 +n\8 +..., and this sum converges to n

MadaBit
  • 145
  • 7