In algorithm analysis, we use asymptotic notations to describe the performance or complexity of an algorithm in relation to the size of the input, especially as the input grows towards infinity. Asymptotic notations help in comparing algorithms and understanding their efficiency in a way that abstracts away constant factors and focuses on how the algorithm behaves for large inputs.
The three most commonly used asymptotic notations are Big O (O), Omega (Ω), and Theta (Θ). There are also little o and little ω notations, which are less commonly used but still valuable in certain situations.
O(1): Constant time – the algorithm's running time does not depend on the size of the input.
O(log n): Logarithmic time – the algorithm's running time grows logarithmically as the input size increases. Typically seen in divide-and-conquer algorithms.
O(n): Linear time – the running time grows linearly with the size of the input.
O(n log n): Log-linear time – commonly seen in efficient sorting algorithms like MergeSort or QuickSort.
O(n²): Quadratic time – the running time grows quadratically with the input size. Common in algorithms with nested loops.
O(2^n): Exponential time – the running time doubles with each additional input element. This is typical for algorithms that solve problems through brute force.
If an algorithm has a time complexity of O(n²), it means that as the input size n increases, the running time grows proportional to the square of the input size.
Ω(1): Constant time – even in the best case, the algorithm will take a constant amount of time.
Ω(n): Linear time – in the best case, the algorithm’s running time grows linearly with the input size.
For a sorting algorithm, if it is guaranteed that it will always require at least Ω(n) operations (such as comparing elements), we know that the algorithm cannot be faster than O(n).
Θ(n log n): Log-linear time – this is the exact time complexity for algorithms like MergeSort and QuickSort on average.
Θ(n²): Quadratic time – when an algorithm has both its upper and lower bounds as quadratic.
If an algorithm has Θ(n²), it means that both the upper bound (worst case) and the lower bound (best case) for the algorithm are quadratic in nature. In this case, the running time grows exactly like n² for large inputs.
If a function is o(n²), it means that as the input size increases, the running time grows strictly slower than n². So, an algorithm that runs in O(n log n) would have a time complexity of o(n²).
If an algorithm runs in ω(n), it means that for large inputs, the algorithm’s running time grows strictly faster than n. For example, an algorithm running in O(n²) would have a lower bound of ω(n).
| Notation | Description | Best Case | Worst Case | Exact Bound |
|---|---|---|---|---|
| Big O (O) | Upper bound (worst case) | No guarantee | Maximum | No exact bound |
| Omega (Ω) | Lower bound (best case) | Minimum | No guarantee | No exact bound |
| Theta (Θ) | Tight bound (exact bound for both worst and best) | Exact | Exact | Exact bound |
Asymptotic notations allow us to describe the performance of algorithms in terms of their input size, especially for large inputs. These notations give us a way to abstract away constant factors and focus on the growth rate of the algorithm’s time or space complexity:
By using these notations, we can efficiently compare algorithms and understand how their performance scales as the input size increases.
Open this section to load past papers