Curves to show

050100150200151015202530Input size nOperationsn = 20

At n = 20, O(1) does about 1 operations. At n = 20, O(log n) does about 4.3 operations. At n = 20, O(n) does about 20 operations. At n = 20, O(n log n) does about 86.4 operations. At n = 20, O(n²) does about 400 operations and leaves the top of the chart at n = 15. At n = 20, O(2ⁿ) does about 1,048,576 operations and leaves the top of the chart at n = 8.

Approximate operations for n = 20. Logarithms are base 2.
ComplexityOperationsEstimated time at 10⁸ operations per second
O(1)Constant110 ns
O(log n)Logarithmic4.343 ns
O(n)Linear20200 ns
O(n log n)Linearithmic86.4864 ns
O(n²)Quadratic4004.0 µs
O(2ⁿ)Exponential1,048,57610 ms

Logarithms are base 2. In the linear view the chart clips at the top, so the steepest curves leave the plot early. Switch the operations axis to logarithmic to keep every curve in view, or type a larger n to see the table values diverge. Time estimates divide the operation count by an assumed 108 simple operations per second. They are not measurements: hardware, the language runtime, constant factors, memory access, and the input all change real running time.

Code for each class

O(1): constant

Work does not depend on input size.

def first(items):
    return items[0]

O(log n): logarithmic

Each step discards half of what remains.

def binary_search(items, target):
    lo, hi = 0, len(items) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if items[mid] == target:
            return mid
        if items[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

O(n): linear

One pass over the input.

def total(items):
    result = 0
    for x in items:
        result += x
    return result

O(n log n): linearithmic

Sorting dominates, then one linear pass.

def has_duplicates(items):
    items = sorted(items)
    return any(a == b for a, b in zip(items, items[1:]))

O(n2): quadratic

A loop inside a loop over the same input.

def has_pair_sum(items, target):
    for i in range(len(items)):
        for j in range(i + 1, len(items)):
            if items[i] + items[j] == target:
                return True
    return False

O(2n): exponential

Every item doubles the number of branches.

def count_subsets(items, target, i=0):
    if i == len(items):
        return 1 if target == 0 else 0
    take = count_subsets(items, target - items[i], i + 1)
    skip = count_subsets(items, target, i + 1)
    return take + skip

Color key

Reading the notation

Complexities are quick-reference summaries. Actual performance depends on the implementation, the input, and the assumptions behind each operation, so check the linked references when exact guarantees matter.

Keyboard shortcuts

/
Search topics
?
Show this list of shortcuts
r
Open the revision sheet
b
Save or unsave the focused card, or the topic you are reading
l
Mark the focused card, or the topic you are reading, as learned
Space Left arrow Right arrow
In the visualizer: play or pause, step back, step forward
1 to 4 Enter
In the quiz: pick an answer, then go to the next question
Escape
Close this list