Skip to main content
Career Paths
Concepts
Problem Solving Patterns
The Simplified Tech

Role-based learning paths to help you master cloud engineering with clarity and confidence.

Product

  • Career Paths
  • Interview Prep
  • Scenarios
  • AI Features
  • Cloud Comparison
  • Pricing

Community

  • Join Discord

Account

  • Dashboard
  • Credits
  • Updates
  • Sign in
  • Sign up
  • Contact Support

Stay updated

Get the latest learning tips and updates. No spam, ever.

Terms of ServicePrivacy Policy

© 2026 TheSimplifiedTech. All rights reserved.

BackBack
Interactive Explainer

Problem-Solving Patterns

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.

Relevant for:JuniorMid-levelSenior
Why this matters at your level
Junior

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.

Mid-level

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).

Senior

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.

Problem-Solving Patterns

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.

~5 min read
Be the first to complete!
LIVEMissed SLA — Order Reporting System — O(n²) in Production
Breaking News
Development

Engineer tests order deduplication with 100 orders — runs in under 1 second, ships to production

First production run

Report starts on 100,000 orders — O(n²) means 10 billion operations, runtime estimated at 8 hours

CRITICAL
T+8hrs

Report finishes after SLA cutoff — next-day delivery orders not flagged, duplicates shipped

CRITICAL
Customer impact

Duplicate charges appear on customer cards — support tickets spike, chargebacks filed

CRITICAL
Fix deployed

Sliding window pattern applied: O(n log n) sort + O(n) scan. Report now runs in 30 minutes as specified.

—nightly report runtime from O(n²) nested loops — missing the sliding window pattern
—complexity reduction after applying the correct pattern

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?

Test your assumption first

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?

What you'll learn
  • Pattern 1 — Two Pointers: two indices moving through a sorted array from opposite ends or at different speeds. Use when: find a pair summing to a target, palindrome check, remove duplicates in-place
  • Pattern 2 — Sliding Window: a window of fixed or variable size sliding through an array. Use when: longest substring with K distinct characters, maximum sum subarray of size K, minimum window containing all characters
  • Pattern 3 — Fast & Slow Pointers: one pointer moves one step, another moves two. Use when: detect a cycle in a linked list, find the middle of a linked list, find the start of a cycle
  • Pattern 4 — BFS/DFS on trees and graphs: covered in the trees and graphs pages. Use when: level-order traversal, shortest path, all paths, connected components
  • Pattern 5 — Binary Search on the answer: binary search where the "array" is the answer space. Use when: minimum/maximum value that satisfies a condition, find the K-th element
  • The meta-skill: recognise the pattern in the first 2 minutes, before writing any code. State the pattern name, justify it, then implement.

Lesson outline

What this looks like in real life

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 insight that makes it work

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

Situation
Before
After

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.”

Walk through it in plain English

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.

1

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.

2

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).

3

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.

4

Left (index 3) is now >= right (index 3). Pointers have crossed. Stop.

5

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.

6

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.

Now in code

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.

patterns.py
1# PATTERN 1: Two Pointers (sorted array, find pair summing to target)
2def two_sum_sorted(arr: list, target: int) -> list:
3 left, right = 0, len(arr) - 1
4 while left < right:
5 s = arr[left] + arr[right]
6 if s == target: return [left, right]
7 elif s < target: left += 1 # need larger sum
Moving 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.
8 else: right -= 1 # need smaller sum
9 return []
10
11# PATTERN 2: Sliding Window (max sum subarray of size k)
12def max_subarray_sum(arr: list, k: int) -> int:
13 window_sum = sum(arr[:k]) # initial window
14 max_sum = window_sum
15 for 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.
16 window_sum += arr[i] - arr[i-k] # slide: add right, remove left
17 max_sum = max(max_sum, window_sum)
18 return max_sum
19
20# 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.
22 slow, fast = head, head
23 while 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.
24 slow = slow.next
25 fast = fast.next.next # fast moves 2, slow moves 1
26 if slow is fast: return True # they met inside the cycle
27 return False

The trap — what most people try first

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

Bug
# 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
Fix
# 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 step

The 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.

When to reach for this

Is the input sorted and do you need pairs summing to a target, or two pointers meeting?
YesTwo Pointers — left and right indices moving inward, O(n) single pass
NoContinue...
Do you need the best subarray or substring satisfying a size or character constraint?
YesSliding Window — expand right, contract left when constraint is violated, O(n)
NoContinue...
Is the input a linked list and do you need cycle detection or the middle node?
YesFast & Slow Pointers — slow moves 1 step, fast moves 2, O(n) time O(1) space
NoContinue...
Are you finding the minimum or maximum value that satisfies a binary condition?
YesBinary Search on Answer — binary search over the answer space, O(n log(answer range))
NoBFS or DFS for graph or tree problems, DP for overlapping subproblems

How fast is it?

PatternReplacesComplexity
Two Pointers (sorted array)Nested loops O(n²) for pair problemsFast (O(n))
Sliding Window (fixed or variable size)Nested loops O(n²) or O(n³) for subarray problemsFast (O(n))
Fast & Slow PointersVisited set O(n) space for cycle detectionFast (O(n) time, O(1) space)
Binary Search on AnswerLinear scan O(n) over the answer spaceFast (O(log(answer range) × n)

Exam Answer vs. Production Reality

1 / 1

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

How this might come up in interviews

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:

  • Two Sum II — sorted array (Two Pointers)
  • Longest substring without repeating characters (Sliding Window)
  • Linked List Cycle (Fast & Slow)
  • Find minimum in rotated sorted array (Binary Search)
  • Container with most water (Two Pointers)

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)

🧠Mental Model

💡 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 paths

Discussion

Questions? Discuss in the community or start a thread below.

Join Discord

In-app Q&A

Sign in to start or join a thread.

Sign in to track your progress and mark lessons complete.

Discussion

Questions? Discuss in the community or start a thread below.

Join Discord

In-app Q&A

Sign in to start or join a thread.