alicew
alicew

Reputation: 275

Python Time Complexity (run-time)

def f2(L):
    sum = 0
    i = 1
    while i < len(L):
        sum = sum + L[i]
        i = i * 2
    return sum

Let n be the size of the list L passed to this function. Which of the following most accurately describes how the runtime of this function grow as n grows?

(a) It grows linearly, like n does. (b) It grows quadratically, like n^2 does.

(c) It grows less than linearly. (d) It grows more than quadratically.

I don't understand how you figure out the relationship between the runtime of the function and the growth of n. Can someone please explain this to me?

Upvotes: 5

Views: 11858

Answers (6)

jdi
jdi

Reputation: 92647

I am not a computer science major and I don't claim to have a strong grasp of this kind of theory, but I thought it might be relevant for someone from my perspective to try and contribute an answer.

Your function will always take time to execute, and if it is operating on a list argument of varying length, then the time it takes to run that function will be relative to how many elements are in that list.

Lets assume it takes 1 unit of time to process a list of length == 1. What the question is asking, is the relationship between the size of the list getting bigger vs the increase in time for this function to execute.

This link breaks down some basics of Big O notation: http://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/

If it were O(1) complexity (which is not actually one of your A-D options) then it would mean the complexity never grows regardless of the size of L. Obviously in your example it is doing a while loop dependent on growing a counter i in relation to the length of L. I would focus on the fact that i is being multiplied, to indicate the relationship between how long it will take to get through that while loop vs the length of L. Basically, try to compare how many loops the while loop will need to perform at various values of len(L), and then that will determine your complexity. 1 unit of time can be 1 iteration through the while loop.

Hopefully I have made some form of contribution here, with my own lack of expertise on the subject.

Update
To clarify based on the comment from ch3ka, if you were doing more than what you currently have inside your with loop, then you would also have to consider the added complexity for each loop. But because your list lookup L[i] is constant complexity, as is the math that follows it, we can ignore those in terms of the complexity.

Upvotes: 10

ch3ka
ch3ka

Reputation: 12178

ok, since this is homework:

this is the code:

def f2(L):
    sum = 0
    i = 1
    while i < len(L):
        sum = sum + L[i]
        i = i * 2
    return sum

it is obviously dependant on len(L).

So lets see for each line, what it costs:

sum = 0
i = 1
# [...]
return sum

those are obviously constant time, independant of L. In the loop we have:

    sum = sum + L[i] # time to lookup L[i] (`timelookup(L)`) plus time to add to the sum (obviously constant time)
    i = i * 2 # obviously constant time

and how many times is the loop executed? it's obvously dependant on the size of L. Lets call that loops(L)

so we got an overall complexity of

loops(L) * (timelookup(L) + const)

Being the nice guy I am, I'll tell you that list lookup is constant in python, so it boils down to

O(loops(L)) (constant factors ignored, as big-O convention implies)

And how often do you loop, based on the len() of L?

(a) as often as there are items in the list (b) quadratically as often as there are items in the list?

(c) less often as there are items in the list (d) more often than (b) ?

Upvotes: 12

ch3ka
ch3ka

Reputation: 12178

it's O(log(len(L))), as list lookup is a constant time operation, independant of the size of the list.

Upvotes: 0

Alfe
Alfe

Reputation: 59586

Consider what happens with an input of length n=10. Now consider what happens if the input size is doubled to 20. Will the runtime double as well? Then it's linear. If the runtime grows by factor 4, then it's quadratic. Etc.

Upvotes: 3

g19fanatic
g19fanatic

Reputation: 10961

When you look at the function, you have to determine how the size of the list will affect the number of loops that will occur.

In your specific situation, lets increment n and see how many times the while loop will run.

n = 0, loop = 0 times
n = 1, loop = 1 time
n = 2, loop = 1 time
n = 3, loop = 2 times
n = 4, loop = 2 times

See the pattern? Now answer your question, does it:

(a) It grows linearly, like n does. (b) It grows quadratically, like n^2 does.

(c) It grows less than linearly. (d) It grows more than quadratically.

Checkout Hugh's answer for an empirical result :)

Upvotes: 2

Hugh Bothwell
Hugh Bothwell

Reputation: 56694

Here's a quick-and-dirty way to find out:

import matplotlib.pyplot as plt

def f2(L):
    sum = 0
    i = 1
    times = 0
    while i < len(L):
        sum = sum + L[i]
        i = i * 2
        times += 1    # track how many times the loop gets called
    return times

def main():
    i = range(1200)
    f_i = [f2([1]*n) for n in i]
    plt.plot(i, f_i)

if __name__=="__main__":
    main()

... which results in

plot of function loops vs parameter size

Horizontal axis is size of L, vertical axis is how many times the function loops; big-O should be pretty obvious from this.

Upvotes: 4

Related Questions