1

I have been given a simply Python programme as such:

def boo(n):
    if n == 1:
        return 1
    else:
        return boo(n/2) + boo(n/2)

To boo, I have to find out the time complexity of the function. My idea is that since each n makes a call to two more boo's, the time complexity is O(2^n). However, it has been revealed that this is wrong. The answer has been revealed to me that the actual time complexity is O(n) without rationale given. My hunch is that boo(n/2) + boo(n/2) can be treated as 2*boo(n/2), but I am highly suspicious of this as I have seen similar scenarios before, and I vaguely remember that boo(n/2) + boo(n/2) cannot be equated to 2*boo(n/2) in terms of processing steps.

What would be a more appropriate way to understand this? I am still struggling with the ideas in order of growth (space and time complexity), so if anyone has any general advice or material that can possibly help me, I greatly welcome them. Thank you very much!

5
  • 2
    It is closer to about O(log2(n)) Commented Sep 25, 2020 at 14:46
  • 1
    If n is not a power of 2, this will recurse infinitely. Commented Sep 25, 2020 at 14:46
  • 1
    This may be naive, but it seems to me like boo(2048) calls boo(1024) twice, so doubling the input number doubles the number of operations. Which would make it O(n). Leaving aside the issue of using / instead of //. Commented Sep 25, 2020 at 14:50
  • 1
    @khelwood: Not naive, that's how it works. In raw calls, it always does n * 2 - 1 total calls, which is O(n) overall. Commented Sep 25, 2020 at 14:53
  • boo(n/2) + boo(n/2) does boo(n/2) twice, while 2*boo(n/2) does it only once, so clearly they can't be equally complex (unless that complexity is constant, but then it would be independent of n, so...). Commented Sep 25, 2020 at 15:00

1 Answer 1

3

This code is O(∞), as a non-power-of-two input will never complete (it will go from > 1 to < 1 without ever being == 1).

For powers of 2 (or if properly rewritten to do boo(n // 2) and not recurse infinitely), it's O(n), as each step halves the input, but then does that halved work twice, leading to overall linear performance (to be precise, boo is called 2n - 1 times for n being a power of 2). Changing the final line to return boo(n // 2) * 2 would get it to O(log n) performance.

Sign up to request clarification or add additional context in comments.

4 Comments

I wonder if this was originally written for Python 2.x, which does integer arithmetic and will always reach 1.
@Barmar: That seems likely. It could be written with // in Python 2 as well though (// works long before it was required to achieve floor division) to make it portable. Either way, when it works as expected, the code is clearly O(n).
Understood now! I suppose the code was written too simplistically. But now assuming that n is a power of 2, is it fair to say that, first, the time complexity of 2*boo(n/2) is O(logn) because we are "dividing and conquering" by a factor of 2. But in the case of boo(n/2) + boo(n/2), the operation is performed in 2 "branches", hence it becomes O(n). Is this a fair evaluation?
@a9302c: You got it. It's splitting the work in half, then doing that halved work twice, so it's just "doing the original work" in a funny way. If you like to think of it this way, it's doing O(2 ** log₂n) work (the log₂n from the halving, the 2** from the doubling), which of course is equivalent to O(n).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.