15 tutorials
Algorithms tutorials
Every Algorithms guide on the site, newest first. Each one is built around code you can run.
Algorithm articles usually fail in one of two ways: they show a solution without the reasoning that produces it, or they explain the idea and leave the implementation as an exercise. The walkthroughs here do both — the invariant first, then code that runs, then the complexity and the edge cases that break a naive version.
The material is organised by technique rather than by problem, because the technique is what transfers. Binary search on a sorted array is one problem; recognising that a problem has a monotonic predicate you can binary-search over is the skill. The same holds for the sliding window, two pointers, and the recurrence patterns behind dynamic programming.
Implementations are in Java unless a language makes a particular point clearer. Off-by-one handling is written out explicitly rather than hidden behind a helper, since that is where most of these go wrong.
Each walkthrough follows the same order, because the order is the method. First the brute-force solution, stated plainly and with its complexity, so there is a baseline. Then the observation that makes it unnecessary — the sorted property, the monotonic predicate, the overlapping subproblem. Then the improved implementation, and finally the complexity that justifies the extra work.
That structure exists because jumping straight to an optimal solution is where explanations lose people. Knowing that a problem can be solved in linear time is not the same as seeing why, and the second is the only part that helps with a problem you have not met before.
The implementations favour clarity over cleverness. A tight one-liner that computes the right answer is worse than eight readable lines when the point is to understand the method, and anything genuinely subtle is commented in place rather than explained afterwards.
Complexity notation describes how a cost grows, not how long something takes. An O(n log n) sort can lose to an O(n^2) one on a few dozen elements, because the constant factors and the memory access pattern dominate at that size. The guides state the asymptotic cost and then say where the crossover actually sits, because the second number is the one that decides which implementation you ship. Locality matters for the same reason: an array walked in order and a linked list of the same length have identical complexity and very different behaviour once the data no longer fits in cache.
A note on how these are written. Each one states the brute-force solution first, because it is the reference the fast version has to agree with, and then names the single observation that collapses the complexity: the sorted half in a rotated array, the running maximum in a sliding window, the stale frequency count that is safe to leave stale. The code is short; the paragraph explaining why the pointer moves that way is the part worth reading twice.
All Algorithms tutorials
- Squares of a Sorted Array Algorithms · 13 min
- Longest Substring with Same Letters After Replacement Algorithms · 12 min
- Sliding Window Maximum Explained Algorithms · 14 min
- Maximum Sum Subarray of Size K Algorithms · 13 min
- Find the Minimum in a Rotated Sorted Array Algorithms · 13 min
- Equal Subset Sum Partition Problem Algorithms · 14 min
- The 0/1 Knapsack Problem Explained Algorithms · 12 min
- Valid Parentheses Problem Explained Algorithms · 13 min
- Binary Search: Iterative and Recursive in Java Algorithms · 14 min
- Longest Palindromic Substring Algorithms · 14 min
- Search an Element in a Rotated Sorted Array Algorithms · 14 min
- Design an LRU Cache Data Structure Algorithms · 14 min
- Reverse a Singly Linked List Algorithms · 13 min
- Three Sum Problem: Find All Triplets With a Given Sum Algorithms · 13 min
- Two Sum Problem: Solutions in Java Algorithms · 13 min
Frequently asked questions
Which language are the implementations in?
Java by default. The reasoning is language-independent and the code translates directly.
Is complexity analysis included?
Yes — time and space for every implementation, including the cases where the average and the worst case diverge.
Are these organised by problem or by technique?
By technique. Recognising which technique a problem calls for is the part that transfers between problems.
Do they cover edge cases?
Explicitly. Empty inputs, single elements, duplicates and integer overflow in the midpoint calculation are all handled in the code rather than mentioned in passing.
Do the articles show the brute-force solution first?
Yes, with its complexity, so the improvement has something to improve on. Skipping it is what makes optimal solutions look like tricks.
How is integer overflow handled in binary search?
The midpoint is computed as low + (high - low) / 2 rather than (low + high) / 2, and the reason is spelled out rather than left as a convention.