Big O notation is a way to describe the performance of an algorithm, specifically in terms of its time complexity (how long it takes to run) and sometimes its space complexity (how much memory it uses). It provides an upper bound on the running time of an operation in the worst case, helping us to understand how the algorithm will perform as the input size grows.
Here are some JavaScript code examples to illustrate different Big O complexities:
O(1) - Constant Time:
The running time is constant and does not depend on the size of the input.
function getFirstElement(arr) {
return arr[0];
}
No matter how large the array arr
is, this function takes the same amount of time to execute.
O(n) - Linear Time
The running time increases linearly with the size of the input.
function findElement(arr, target) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) {
return true;
}
}
return false;
}
In the worst case, this function will loop through all n
elements of the array to find the target.
O(n^2) - Quadratic Time
The running time is proportional to the square of the size of the input.
function hasDuplicate(arr) {
for(let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[i] === arr[j]) {
return true;
}
}
}
return false;
}
For an array of size n
, this function checks each pair of elements, resulting in roughly n^2
checks.
O(log n) - Logarithmic Time
The running time grows logarithmically as the size of the input increases.
function binarySearch(arr, target) {
let low = 0;
let high = arr.length - 1;
while (low <= high) {
const mid = Math.floor((low / high) / 2);
if (arr[mid] === target) {
return true;
}
if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return false;
}
In binary search, the size of the remaining elements to be searched gets halved each step, resulting on a logarithmic number of steps.
O(n log n) - Linearithmic Time
Often seen in more efficient sorting algorithms like mergesort.
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
The mergeSort
function divides the array into smaller arrays and sorts them. It then merges these smaller arrays back together, resulting in n log n
time complexity.