1

I had a quiz in my class and didn't do so well on it. I'm looking to find out if someone can explain to me what I did wrong here - our professor is overwhelmed with office hours as we moved online so I thought I'd post here.

def functionC(L):
    for i in range(len(L)):
        if L[i] == i:
            v = L.pop(i)
            L.insert(i, 2*v)
    return

I supplied the following answer:

The above function is O(n) because the for-loop grows with the size of L. The pop and insert functions are both constant time.

the word time is crossed out, but there is no other explanation as to why I received 6/10 for the question. What did I get wrong in this and why?

Here is an image of the question and my answer to prove the quiz has already been graded and handed back.

enter image description here

DMellon
  • 113
  • 3

2 Answers2

3

You need to be aware that the complexity of insert and pop can be $O(n)$ in python ($n = \text{length($L$)}$). Hence, the time complexity can be $O(n^2)$.

OmG
  • 3,612
  • 1
  • 15
  • 23
2

As pointed out by Yuval Filmus, you should ask that question to your professor.

I'll just point out some possible issues. I will also assume that $L$ is a python list.

  • $n$ is never defined, so it is unclear what $O(n)$ even means.

  • The wording "the for loop grows with the size of L" is a bit odd. A for loop does not grow. Its number of iterations is equal to the size (or better, length) of L.

  • From here, it seems that lists in python are implemented using arrays*. The $L.\mbox{pop}(i)$ operation requires $\Theta( 1 + \mbox{len}(L)-i )$ time** and, in your case, you can have $\Theta(\mbox{len}(L))$ iterations for which $\mbox{len}(L)-i = \Theta(\mbox{len}(L))$. The same holds for $L.\mbox{insert}(i, \cdot)$. The overall time complexity is then $O((\mbox{len}(L))^2)$. Consider, for example, the list $L = \langle 0, 1, \dots, \mbox{len}(L) \rangle$.

*These arrays are dynamically resized when elements are appended and not enough capacity is available. This only guarantees a constant amortized time per operation, so even a single operation on a list $L$ that you got as a parameter could cost up to $O(\mbox{len}(L))$ worst-case time. This is not a concern in your code since the initial capacity of $L$ is never exceeded.

**Some sources report that $L\mbox{.pop}(i)$ requires $O(i)$ time. The above argument still holds in this case.

Steven
  • 29,724
  • 2
  • 29
  • 49