The five reusable algorithmic patterns that underlie the majority of coding interview problems and production bottlenecks. Recognising the pattern before writing a line of code is the skill that separates engineers who solve problems in 20 minutes from those who spend 20 minutes and get nowhere.
Know two pointers and sliding window cold. These two patterns cover roughly 30% of easy and medium interview problems. Implement at least 3 problems of each type until you recognise them instantly.
Apply all five patterns fluently. Recognise pattern variants: two pointers on an unsorted array (use hash table), sliding window with a character frequency map. Know when to combine patterns (BFS + sliding window for path problems).
Use pattern knowledge in code review to identify O(n²) bottlenecks and propose O(n) refactors. Communicate pattern names in design discussions so junior engineers develop the vocabulary. Write problems that test pattern recognition during technical interviews.
The five reusable algorithmic patterns that underlie the majority of coding interview problems and production bottlenecks. Recognising the pattern before writing a line of code is the skill that separates engineers who solve problems in 20 minutes from those who spend 20 minutes and get nowhere.
Engineer tests order deduplication with 100 orders — runs in under 1 second, ships to production
Report starts on 100,000 orders — O(n²) means 10 billion operations, runtime estimated at 8 hours
CRITICALReport finishes after SLA cutoff — next-day delivery orders not flagged, duplicates shipped
CRITICALDuplicate charges appear on customer cards — support tickets spike, chargebacks filed
CRITICALSliding window pattern applied: O(n log n) sort + O(n) scan. Report now runs in 30 minutes as specified.
The question this raises
The same problem can be solved in O(n) or O(n²) depending on which pattern you recognise. What are the five patterns that cover most interview problems, and how do you recognise which one applies?
You need to find the longest substring in a string with no repeating characters (for example, in "abcabcbb" the answer is "abc" with length 3). What is the most efficient approach?
Lesson outline
The sliding window behind the order deduplication
To find duplicate orders within 24 hours: sort orders by timestamp. Place a LEFT pointer at the first order and a RIGHT pointer sliding forward. When an order at RIGHT is within 24 hours of the order at LEFT, it is in the window. When it is more than 24 hours later, move LEFT forward. Every order is processed once: O(n). Compare this to the naive approach: for every order, scan all other orders. Every order is compared to every other order: O(n²). Same correct answer, 333x faster on 100,000 orders.
5 Core Patterns
Two pointers: left, right = 0, len-1 Sliding window: left=0; for right in range(n) Fast/slow: slow=head; fast=head Binary search: left, right = min_ans, max_ans
Use for: Before writing any code: identify which pattern applies. Two Pointers (sorted array, pairs). Sliding Window (subarray/substring with constraint). Fast & Slow (linked list cycles). BFS/DFS (graphs, trees). Binary Search on Answer (min/max satisfying condition).
The key insight: every pattern has a tell. You do not need to derive the algorithm from scratch. You need to hear the problem and match it to a pattern. The tell is usually in what the problem asks and what properties the input has.
How this concept changes your thinking
Problem says "sorted array, find two numbers that sum to target"
“I try every pair: nested loops, O(n²). Works but slow.”
“Two pointers. Sorted means: if current sum is too small, move left pointer right (increase left value). If too large, move right pointer left. O(n) single pass.”
Problem says "longest substring with at most K distinct characters"
“I try every substring, check how many distinct characters it has. O(n³).”
“Sliding window. Expand right, contract left when distinct count exceeds K. Each character enters and leaves the window exactly once. O(n).”
Problem says "find if a linked list has a cycle"
“I store every visited node in a set. O(n) space.”
“Fast and slow pointers. Slow moves one step, fast moves two. If there is a cycle, fast will lap slow and they will meet. O(1) extra space.”
Two pointers: find all pairs in sorted array [1, 2, 3, 4, 6] that sum to 7
01
Place left at index 0 (value 1) and right at index 4 (value 6). Sum = 1+6 = 7. Match! Record pair (1,6). Move both pointers inward.
02
Left at index 1 (value 2), right at index 3 (value 4). Sum = 2+4 = 6. Less than 7, so we need a larger sum. Move left pointer right (increase smaller value).
03
Left at index 2 (value 3), right at index 3 (value 4). Sum = 3+4 = 7. Match! Record pair (3,4). Move both pointers inward.
04
Left (index 3) is now >= right (index 3). Pointers have crossed. Stop.
05
Result: pairs (1,6) and (3,4) sum to 7. Total: 4 operations for a 5-element array. Nested loops: 10 operations. At 10,000 elements: two pointers does 10,000 operations, nested loops does 100,000,000.
06
The key: why does moving left right always work? The array is sorted. If sum < target, the only way to increase sum is to increase the smaller value (move left right). If sum > target, the only way to decrease sum is to decrease the larger value (move right left). We never miss a valid pair.
Place left at index 0 (value 1) and right at index 4 (value 6). Sum = 1+6 = 7. Match! Record pair (1,6). Move both pointers inward.
Left at index 1 (value 2), right at index 3 (value 4). Sum = 2+4 = 6. Less than 7, so we need a larger sum. Move left pointer right (increase smaller value).
Left at index 2 (value 3), right at index 3 (value 4). Sum = 3+4 = 7. Match! Record pair (3,4). Move both pointers inward.
Left (index 3) is now >= right (index 3). Pointers have crossed. Stop.
Result: pairs (1,6) and (3,4) sum to 7. Total: 4 operations for a 5-element array. Nested loops: 10 operations. At 10,000 elements: two pointers does 10,000 operations, nested loops does 100,000,000.
The key: why does moving left right always work? The array is sorted. If sum < target, the only way to increase sum is to increase the smaller value (move left right). If sum > target, the only way to decrease sum is to decrease the larger value (move right left). We never miss a valid pair.
The five patterns in code — each shown at its most fundamental. The structure of each is the pattern itself: learn the structure and you can apply it to any variant of the problem.
1# PATTERN 1: Two Pointers (sorted array, find pair summing to target)2def two_sum_sorted(arr: list, target: int) -> list:3left, right = 0, len(arr) - 14while left < right:5s = arr[left] + arr[right]6if s == target: return [left, right]7elif s < target: left += 1 # need larger sumMoving left right when sum < target is safe because arr is sorted: any pair involving the current right and a left to the left of current left gives an even smaller sum. We will not miss any pair.8else: right -= 1 # need smaller sum9return []1011# PATTERN 2: Sliding Window (max sum subarray of size k)12def max_subarray_sum(arr: list, k: int) -> int:13window_sum = sum(arr[:k]) # initial window14max_sum = window_sum15for i in range(k, len(arr)):Sliding window core: add the new right element (arr[i]) and subtract the element that just left the window (arr[i-k]). One addition and one subtraction per step instead of re-summing the window.16window_sum += arr[i] - arr[i-k] # slide: add right, remove left17max_sum = max(max_sum, window_sum)18return max_sum1920# PATTERN 3: Fast & Slow Pointers (detect cycle in linked list)21def has_cycle(head) -> bool:Check fast and fast.next before dereferencing. In a list with no cycle, fast reaches None first. Checking fast.next prevents a NullPointerException on the last node.22slow, fast = head, head23while fast and fast.next:"slow is fast" (identity check, not equality) is intentional. Two different nodes with the same value would incorrectly report a cycle with ==. We want the same node object, not equal values.24slow = slow.next25fast = fast.next.next # fast moves 2, slow moves 126if slow is fast: return True # they met inside the cycle27return False
The natural approach to almost every array problem is nested loops: for each element, try every other element. This is always O(n²) and is almost never the intended solution. The fix is recognising that sorted input + two pointers, or a windowed constraint + sliding window, reduces the problem to O(n).
Nested loops when two pointers or sliding window applies
# SLOW: O(n^2) nested loops for pair sum
def two_sum_naive(arr, target):
for i in range(len(arr)):
for j in range(i+1, len(arr)):
if arr[i] + arr[j] == target:
return [i, j]
return []
# At 100,000 elements: 5 billion iterations
# Works in dev with 100 items, hangs in production# FAST: O(n) two pointers (requires sorted input)
def two_sum_sorted(arr, target):
left, right = 0, len(arr) - 1
while left < right:
s = arr[left] + arr[right]
if s == target: return [left, right]
elif s < target: left += 1
else: right -= 1
return []
# At 100,000 elements: 100,000 iterations maximum
# The sorted invariant lets us eliminate half each stepThe nested loop approach checks every pair: n*(n-1)/2 pairs for n elements. At 100,000 elements that is 5 billion checks. Two pointers on sorted input does at most n checks because each step eliminates either the smallest or largest element from future consideration. The same logic that makes binary search fast (eliminating half the candidates) makes two pointers fast: each step, one element is permanently excluded.
| Pattern | Replaces | Complexity |
|---|---|---|
| Two Pointers (sorted array) | Nested loops O(n²) for pair problems | Fast (O(n)) |
| Sliding Window (fixed or variable size) | Nested loops O(n²) or O(n³) for subarray problems | Fast (O(n)) |
| Fast & Slow Pointers | Visited set O(n) space for cycle detection | Fast (O(n) time, O(1) space) |
| Binary Search on Answer | Linear scan O(n) over the answer space | Fast (O(log(answer range) × n) |
Problem-Solving Patterns
📖 What the exam expects
The five core patterns: Two Pointers (sorted array, pairs, O(n)), Sliding Window (subarray/substring constraint, O(n)), Fast & Slow Pointers (linked list cycles, O(n) time O(1) space), BFS/DFS (graphs and trees, O(V+E)), Binary Search on Answer (O(n log(answer range))). State the pattern and justify it before writing code.
Toggle between what certifications teach and what production actually requires
Pattern problems are the majority of coding interviews at every level. The question is almost always solvable in O(n) or O(n log n) using one of the five patterns. The interview is testing whether you recognise which one applies and whether you can justify it. The correct pattern + wrong justification is a red flag. The wrong pattern + confident justification of why you chose it is also useful information for the interviewer.
Common questions:
Strong answer: names the pattern in the first 30 seconds / justifies the pattern with a property of the input / walks through a tiny example before coding / handles edge cases (empty input, single element, all-same values) proactively / can relate the pattern to a real production scenario when asked
Red flags: jumps to nested loops without considering patterns / cannot name the pattern they are using / uses a pattern without being able to justify why it terminates correctly / only tests the happy path (no empty input, no all-same-character input)
💡 Analogy
Imagine you are a plumber called to fix a leak. You do not start by randomly trying tools. You listen for the leak, identify the type (pipe joint? valve? pressure?), and reach for the specific tool for that type. Algorithmic patterns are the plumber's tool recognition: the moment you hear "find a pair summing to a target in a sorted array" you reach for two pointers, not a nested loop. The skill is pattern recognition, not memorisation of solutions.
⚡ Core Idea
Most coding interview problems and many production bottlenecks are instances of five core patterns. Recognising the pattern gives you the algorithm. The pattern recognition comes from asking four questions: What is moving? (pointers, a window, indices). What is the invariant I am maintaining? What does finding the answer look like? What is the termination condition? Once you answer these four questions, the code writes itself.
🎯 Why It Matters
An engineer who knows ten specific solutions will struggle with the eleventh problem. An engineer who knows five patterns will recognise that the eleventh problem is a sliding window variant and implement it correctly in 10 minutes. Pattern knowledge compounds: once you know two pointers, you recognise two-pointer problems in graphs (BFS meeting in the middle), in trees (left and right pointers), and in strings (palindrome check). The patterns transfer.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.