| Time Complexity | Algorithm |
|---|---|
| O(1) | Constant |
| O(log n) | Logarithmic |
| O(n) | Linear |
| O(n log n) | Linearithmic |
| O(n * log(n)) | Loglinear |
| O(n2) | Polynomial (Quadratic) |
| O(n 3 ) | Polynomial (Cubic) |
| O(2 n ) | Exponential |
| O(n!) | Factorial |
Click algorithm name for more details
| n | O(1) |
|---|---|
| 1 | ~1 |
| 2 | ~1 |
| 3 | ~1 |
| ... | ... |
| 128 | ~1 |
function constant1(n) { return n * 2 + 1; } function constant2(n) { for (let i = 1; i <= 100; i++) { console.log(i); } }
| n | O(log2(n)) |
|---|---|
| 2 | ~1 |
| 4 | ~2 |
| 8 | ~3 |
| 16 | ~4 |
| ... | ... |
| 128 | ~7 |
function logarithmic1(n) { if (n <= 1) return; logarithmic1(n / 2); } function logarithmic2(n) { let i = n; while (i > 1) { i /= 2; } }
| n | O(n) |
|---|---|
| 1 | ~1 |
| 2 | ~2 |
| 3 | ~3 |
| ... | ... |
| 128 | ~128 |
function linear1(n) { for (let i = 1; i <= n; i++) { console.log(i); } } function linear2(array) { for (let i = 0; i < array.length; i++) { console.log(i); } } function linear3(n) { if (n === 1) return; linear3(n - 1); }
| n | O(n * log2(n)) |
|---|---|
| 2 | ~2 |
| 4 | ~8 |
| 8 | ~24 |
| ... | ... |
| 128 | ~896 |
function loglinear(n) { if (n <= 1) return; for (let i = 1; i <= n; i++) { console.log(i); } loglinear(n / 2); loglinear(n / 2); }
n is the size of the input, c is a fixed constant| n | O(n2) |
|---|---|
| 1 | ~1 |
| 2 | ~4 |
| 3 | ~9 |
| ... | ... |
| 128 | ~16,384 |
| n | O(n3) |
|---|---|
| 1 | ~1 |
| 2 | ~8 |
| 3 | ~27 |
| ... | ... |
| 128 | ~2,097,152 |
// O(n^2) function quadratic(n) { for (let i = 1; i <= n; i++) { for (let j = 1; j <= n; j++) {} } } // O(n^3) function cubic(n) { for (let i = 1; i <= n; i++) { for (let j = 1; j <= n; j++) { for (let k = 1; k <= n; k++) {} } } }
n is the size of the input and c is some fixed constant| n | O(2n) |
|---|---|
| 1 | ~2 |
| 2 | ~4 |
| 3 | ~8 |
| ... | ... |
| 128 | ~3.4028 * 1038 |
| n | O(23) |
|---|---|
| 1 | ~3 |
| 2 | ~9 |
| 3 | ~27 |
| 3 | ~81 |
| ... | ... |
| 128 | ~1.1790 * 1061 |
// O(2^n) function exponential2n(n) { if (n === 1) return; exponential_2n(n - 1); exponential_2n(n - 1); } // O(3^n) function exponential3n(n) { if (n === 0) return; exponential_3n(n - 1); exponential_3n(n - 1); exponential_3n(n - 1); }
| n | O(n!) |
|---|---|
| 1 | ~1 |
| 2 | ~2 |
| 3 | ~6 |
| ... | ... |
| 128 | ~3.8562 * 10215 |
function factorial(n) { if (n === 1) return; for (let i = 1; i <= n; i++) { factorial(n - 1); } }
| Sort Name | Time Complexity | Space Complexity |
|---|---|---|
| bubble | O(n^2) | O(1) |
| selection | O(n^2) | O(1) |
| insertion | O(n^2) | O(1) |
| merge | O(n log n) | O(n) |
| quick | O(n log n)/O(n^2) | O(n)/O(log n) |
| binary | O(log(n)) | O(1) |
Click sort name for more details
Time Complexity: Quadratic O(n^2)
Space Complexity: O(1)
function bubbleSort(array) { let sorted = false; while (!sorted) { sorted = true; for (let i = 0; i < array.length; i++) { if (array[i] > array[i + 1]) { let temp = arr[i]; array[i] = array[i + 1]; array[i + 1] = temp; sorted = false; } } } return array; }
i - 1
Time Complexity: Quadratic O(n^2)
Space Complexity: O(1)
function selectionSort(array) { for (let i = 0; i < array.length; i++) { let lowest = i; for (let j = 0; j < array.length; j++) { if (array[j] < array[i]) { lowest = j; } } if (lowest !== i) { let temp = array[i]; array[i] = array[lowest]; array[lowest] = temp; } } return array; }

Time Complexity: Quadratic O(n^2)
Space Complexity: O(n)
function insertionSort(arr) { for (let i = 1; i < arr.length; i++) { let current = arr[i]; let j = i - 1; while (j > -1 && current < arr[j]) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = current; } return arr; }
Time Complexity: Log Linear O(nlog(n))
Space Complexity: O(n)
// Iterative merge function merge(arr1, arr2) { let result = []; while (arr1.length && arr2.length) { if (arr1[0] < arr2[0]) { result.push(arr1.shift()); } else { result.push(arr2.shift()); } } return [...result, ...arr1, ...arr2]; } // Recursive merge function mergeSort(arr) { if (arr.length <= 1) return arr; const mid = Math.floor(arr.length / 2); const left = mergeSort(arr.slice(0, mid)); const right = mergeSort(arr.slice(mid)); return merge(left, right); }

Time Complexity: Quadratic O(n^2)
Space Complexity: O(n)
function quickSort(array) { if (array.length <= 1) return array; let pivot = array.shift(); let left = array.filter((x) => x < pivot); let right = array.filter((x) => x >= pivot); let sortedLeft = quickSort(left); let sortedRight = quickSort(right); return [...sortedLeft, pivot, ...sortedRight]; }

Time Complexity: Log Time O(log(n))
Space Complexity: O(1)
Recursive Solution
function binarySearch(array, target) { if (array.length === 0) return false; let midPt = Math.floor(array.length / 2); if (array[midPt] === target) { return true; } else if (list[midPt] > target) { return binarySearch(list.slice(0, mid), target); } else { return binarySearch(list.slice(midPt + 1), target); } }
Min Max Solution
function binarySearch(array, target) { let start = 0; let end = array.length - 1; while (start <= end) { let midpoint = Math.floor((start + end) / 2); if (target === array[midpoint]) { return midpoint; } if (target > array[midpoint]) { start = midpoint + 1; } if (target < array[midpoint]) { end = midpoint - 1; } } return -1; }
Memoization is a design pattern used to reduce the overall number of calculations that can occur in algorithms that use recursive strategies to solve
There are two features that comprise memoization:
// Standard Implementation // Time Complexity: O(2^n) // - For each call to fib, we have to make two branches, with n levels to this tree function fib(n) { if (n === 1 || n === 2) return 1; return fib(n - 1) + fib(n - 2); } // Using memoization // Time Complexity: O(n) // - We only ever have to calculate fib(x) one time, every other time that we use it in a larger problem, the result is immediately accessible in our memo // - The memo removes the repeated trees of calculations from our original code function fib(n, memo = {}) { if (n in memo) return memo[n]; // If we already calculated this value, return it if (n === 1 || n === 2) return 1; // Store the result in the memo first before returning // Make sure to pass the memo in to your calls to fib! memo[n] = fib(n - 1, memo) + fib(n - 2, memo); return memo[n]; }
// Using tabulation // Time Complexity: O(n) // - We are iterating through an array directly related to the size of the input and performing a constant number of calculations at each step (adding our two previous values together and storing the result in the array). function fib(n) { // We create a table to track our values as we build them up // We're making it n+1 here so that table[n] lines up with the nth fib number // This is because arrays are zero-indexed. // We could have used an array of length n, but we would have to remember that // the nth fib number would then be stored at table[n-1]. Completely doable, // but I think making them line up is more intuitive. let table = new Array(n + 1); // Seed our table with our starting values. // Again, if we had a table of length n, we could have seeded table[0] = 1 // and table[1] = 1 and had the same final result with our indices shifted. table[0] = 0; table[1] = 1; // Iterate through our input and fill out our table as we go. for (let i = 2; i < table.length; i++) { table[i] = table[i - 1] + table[i - 2]; } // At the end, the final entry in our table is the result we are looking for. // The table holds all of the sub-answers that we used to get to this result. return table[n]; }