Task:
given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
My code:
def search(A):
j=1
while j in A:
j+=1;
return j;
Why is my time complexity O(N^2)?
Task:
given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
My code:
def search(A):
j=1
while j in A:
j+=1;
return j;
Why is my time complexity O(N^2)?
You are doing an O(N)
walk over potentially all the items in the list that are positive.
In every iteration you let python make another O(N)
walk of the list, by asking 'j in A
'? which runs through potentially all elements of A
, searching for j
.
So your complexity becomes: O(N) * O(N) = O(N^2)
Suppose your input is of the form 1..N.
Then your code will perform N iterations, each of which it potentially checks the entire length of the list to see whether the current value of j is in the list. N iterations of checking the entire list of length N gives N * N = N^2.
This is a worst-case example, but we don't know what the typical input is supposed to be. Maybe you know it, maybe you don't. A simple and worst-case-optimal way of doing this would be to sort the list and then find the first 'gap' between items in your list. Something like this:
def my_search(A):
A = [i for i in sorted(A) if i > 0] # Gets rid of <1 values as well
min_pos_val = 1
for val in A:
if val > min_pos_val:
return min_pos_val
min_pos_val += 1
return min_pos_val
The "in" operator is O(N). And the "while" is O(the returned value).
[edit] Let me detail this: your code is equivalent to
j = 1
while True: # is O(the returned j)
if j in A: # is O(N), bec. has to go through the whole array
j += 1
else:
return j
So in a worst case, your algo is indeed O(N^2). In best cases (e.g. if 1 not in A) the algo is only O(N).
If A is a set (not a list nor array.array), it'll be O(N) on average. See details here: https://wiki.python.org/moin/TimeComplexity or Complexity of *in* operator in Python.