Nesting multiplies
Each extra loop over n multiplies the cost by n. Two loops give n squared, three give n cubed.
A set buys a step
Replacing a list with a set turns a scan into one lookup, which can remove a whole factor of n.
A loop inside a loop multiplies the work. That is the shape to look for, and the shape to avoid when n can grow.
About 2 min of reading
Measure nested loops and remove one factor.
Full grid of 4.
Before you run it, say out loud what it will print. Then open the answer.
Triangle of 4.
Before you run it, say out loud what it will print. Then open the answer.
Cube of 3.
Before you run it, say out loud what it will print. Then open the answer.
Set membership loop.
Before you run it, say out loud what it will print. Then open the answer.
Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.
Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.
Each extra loop over n multiplies the cost by n. Two loops give n squared, three give n cubed.
Replacing a list with a set turns a scan into one lookup, which can remove a whole factor of n.
n = 4
steps = 0
for i in range(n):
for j in range(n):
steps += 1
print(steps)
n outer turns times n inner turns is n squared. For 4 that is 16.
n = 4
steps = 0
for i in range(n):
for j in range(i, n):
steps += 1
print(steps)
The inner loop shrinks but the total is about n squared over two. Same class.
n = 3
steps = 0
for i in range(n):
for j in range(n):
for k in range(n):
steps += 1
print(steps)
Three nested loops of n cost n cubed. For 3 that is 27.
rows = [[3, 1], [4, 2], [9, 0]]
steps = 0
for r in rows:
r.sort()
steps += 1
print([len(r) for r in rows])
Sorting inside a loop pays the sort cost every turn. The hidden loop still counts.
a = [1, 2, 3, 4]
steps = 0
for x in a:
steps += 1
if x in a:
steps += 1
print(steps)
Checking membership in a list scans it. Inside a loop that is quadratic.
a = [1, 2, 3, 4]
s = set(a)
steps = 0
for x in a:
steps += 1
if x in s:
steps += 1
print(steps)
Membership in a set is one step on average, so the loop stays linear.
n = 2000
print(n * n)
Two thousand squared is four million steps. That is fine. At fifty thousand it is not.
Each one is defined here on this site. Open the entry for the full definition and the other words it points at.