In python-3.x a range(..) is an object, it does not construct a list. If you perform member checks with an int as item, then it can do that quite fast. The algorithm is a bit complicated, since there are both positive and negative steps. You can look it up on [GitHub]. A simple algorithm with a positive step count (c > 0) for x in range(a, b, c) is something like:
x ≥ a ∧ x < b ∧ mod(x-a, c) = 0.
For a negative step count (c < 0) is is quite similar:
x ≤ a ∧ x > b ∧ mod(x-a, c) = 0.
If we consider the comparisons to be done in O(1) and calculating the modulo as well, it is an O(1) algorithm. In reality for huge numbers, it scales in the number of digits of the numbers, so it is an O(log n) algorithm.
This however only works for ints. Indeed, in case you use floats, complex, other numerical or non-numerical types, it does not perform the above calculations. It will then fall back on iterating over the range(..) object. Which of course can take considerable time. If you have a range of a million elements, it will thus iterate over all these elements and eventually reach the end of the range, and return False, or find a match, and return True. In the future, perhaps some extra functionality can be implemented for some numerical types, but one can not do this in general, since you can define your own numerical type with an equality operation that works differently.
In python-2.x, range(..) is a function that returns a list. Indeed:
>>> range(15)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> type(range(15))
<type 'list'>
In order to check if an element is a member of a list, it will iterate over the list, and check equality for all items until it finds an element that is equal, or the list is exhausted. If we consider checking if two items are equal to be constant time, then this takes linear time O(n). In reality for huge numbers, checking if two numbers are equal, scales linear with the number of "digits", so O(log m) with m the value of that number.
python-2.x has an xrange(..) object as well, but this does not check for membership with the above demonstrated trick.
python - Help with Time Complexity - Computer Science Stack Exchange
What is the worst-case time complexity for the following Python fragment? for i in range(n): work(...) Assume that work(...) is O(n). In this question, the detail about the arguments to the function are not important, so they are shown as (...) O 0(1) O O(2n) O O(n) O O(n) O O(n) Question 10 1 pts What is the worst-case time complexity for the following
python 3.x - "Largest range" - what is the time complexity? - Stack Overflow
runtime analysis - What is the time complexity of this algorithm? - Computer Science Stack Exchange
Your function has constant running time (or linear running time, depending on how range is implemented). I suggest running it step-by-step and seeing what happens.
If this is for Python 3.0 then by this knowledge;
- Your function is constant time
. Since every loop runs once end finishes.
If Python version < 3.0;
def func(n):
for i in range(n): #generates all the numbers at once
for j in range(n - i): #generates all the numbers at once
for k in range(n - j): #generates all the numbers at once
if i + j + k == 0:
break
else:
eval()
if i + j == 0:
break
if i == 0:
break
return n + 1
- Since each loop actually runs once the result will be
assuming that your
evalfunction is in.
Now, you need to make index reach n, rather than go just up to it,
so instead of range(1,n), it should be range(1,m) for some m such that n < m .
To avoid n+1, one also needs m ≤ n+1 . Combining those gives n < m ≤ n+1 .
The simplest such m is obviously m = n+1 , so your initial range should be range(1,n+1).
In Python, range(0,n) iterates through the values 0, 1, 2, .., n-1 (but not n). Therefore, your summation should have been
$$\sum_{i=0}^{n-1} \cdots$$
rather than
$$\sum_{i=1}^{n} \cdots$$
and similarly for the other sums as well.
With this code
for i in range(len(numbers)):
for j in range(i+1,len(numbers)):
if numbers[i] == numbers[j]:
print(numbers[i], "is a duplicated")
breakis the reason why it's O(n^2) because the first Loop is O(n) and the second loop is O(n-i) and then when you multiply you get O(n)*O(n-i)
so o(n^2 -ni)
so o(n^2)