Algorithms Corner
Optional enrichment — practical algorithm concepts explained for beginners, without unnecessary abstraction.
Why Algorithms
You do not need to master algorithms to build web apps. But understanding the basics helps you:
- Write code that performs well with real data sizes
- Talk confidently in technical interviews
- Recognize patterns in problems you have not seen before
This section stays practical and beginner-friendly. Every concept is shown with JavaScript examples.
Big O in Plain English
Big O notation describes how the time (or space) a piece of code needs grows as the input size grows. You do not need the math — just the intuition.
| Notation | Plain English | Example |
|---|---|---|
| O(1) | Constant — same speed no matter how big the input | Looking up a value in an object by key |
| O(n) | Linear — grows proportionally with input | Looping through an array once |
| O(n²) | Quadratic — grows fast, gets slow for large inputs | A loop inside a loop |
| O(log n) | Logarithmic — fast, halves the problem each step | Binary search |
Practical rule: For small inputs (dozens, hundreds), most code is fast enough. For large inputs (thousands, millions), nested loops get expensive fast.
Arrays vs Objects
Knowing when to use each one is one of the most practical algorithm skills.
Arrays are ordered lists. Use them when order matters or when you need to iterate over everything.
const names = ['Alice', 'Bob', 'Carol']
names[0] // O(1) — fast
names.includes('Bob') // O(n) — scans the whole array
Objects are key-value stores. Use them when you need fast lookup by a specific identifier.
const userById = {
'001': { name: 'Alice' },
'002': { name: 'Bob' },
}
userById['002'] // O(1) — instant lookup, regardless of size
The pattern: When you find yourself searching an array repeatedly for the same thing, convert it to an object or Map first.
Maps and Sets
Map is like an object but allows any type as a key and preserves insertion order.
const scores = new Map()
scores.set('Alice', 95)
scores.set('Bob', 87)
scores.get('Alice') // 95
scores.has('Carol') // false
Set stores unique values — duplicates are automatically ignored.
const tags = new Set(['js', 'react', 'js', 'css'])
// tags = set { 'js', 'react', 'css' } — no duplicates
// deduplicate an array
const unique = [...new Set(someArray)]
Stacks and Queues
These are patterns for managing ordered collections of items.
Stack — last in, first out (LIFO). Like a stack of plates.
const stack = []
stack.push('first')
stack.push('second')
stack.pop() // 'second' — removes the last item
Queue — first in, first out (FIFO). Like a line at a store.
const queue = []
queue.push('first')
queue.push('second')
queue.shift() // 'first' — removes the first item
You use these patterns constantly without realizing it — browser history is a stack, task queues are queues.
Recursion Basics
A recursive function calls itself. Every recursive function needs a base case (when to stop) and a recursive case (the self-call that makes progress toward stopping).
function countdown(n) {
if (n <= 0) {
console.log('Done!')
return
}
console.log(n)
countdown(n - 1) // calls itself with a smaller value
}
countdown(3)
// 3
// 2
// 1
// done!
A classic example — factorial:
function factorial(n) {
if (n === 1) return 1 // base case
return n * factorial(n - 1) // recursive case
}
factorial(5) // 120 (5 * 4 * 3 * 2 * 1)
Warning: Always make sure the base case will be reached, or the function will run forever and crash.
Sorting and Searching
JavaScript's built-in sort:
const nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort((a, b) => a - b) // ascending: [1, 1, 2, 3, 4, 5, 6, 9]
nums.sort((a, b) => b - a) // descending
Linear search — scan every element:
function findIndex(arr, target) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) return i
}
return -1
}
// o(n) — works on any array
Binary search — works only on sorted arrays, but much faster:
function binarySearch(arr, target) {
let left = 0
let right = arr.length - 1
while (left <= right) {
const mid = Math.floor((left + right) / 2)
if (arr[mid] === target) return mid
if (arr[mid] < target) left = mid + 1
else right = mid - 1
}
return -1
}
// o(log n) — each step cuts the problem in half
Practice Resources
Once you are comfortable with the basics, these platforms offer good practice problems at beginner to intermediate level:
- LeetCode (opens in new tab) — Filter by Easy. Start with Array and String problems.
- Codewars (opens in new tab) — Start at 8 kyu and work up. Good for short, focused problems.
- HackerRank (opens in new tab) — Has structured problem sets by topic.
- NeetCode (opens in new tab) — Excellent video explanations for common interview problems.
Start with what you know. Build confidence with easier problems before moving to harder ones.