# The Only 25 Patterns You Need to Master DSA

There are thousands of coding problems, but there are far fewer **ways of thinking** about those problems.

That is the central idea behind pattern-based DSA preparation.

You do not need to memorize 500 solutions. You need to recognize that a new problem is often a variation of something you have already solved.

A string problem may secretly be a Sliding Window problem. A linked-list problem may secretly be a Fast & Slow Pointer problem. A scheduling problem may secretly be a Merge Intervals problem. A dependency problem may secretly be a Topological Sort problem. A shortest-path problem may secretly be a Dijkstra problem. And a seemingly impossible optimization problem may simply be Dynamic Programming.

This article organizes DSA into **25 reusable patterns**. For each pattern, you get: why it exists, when to recognize it, pseudocode you can implement from, a worked example, a real-world application, and four hand-picked LeetCode problems (1 Easy, 2 Medium, 1 Hard — with a note wherever LeetCode itself doesn't offer a clean problem at that difficulty).

> **On the links below:** every LeetCode link in this article was checked against LeetCode's own listed difficulty before being included, and **every problem in this version is free** — nothing requires a LeetCode subscription. A few patterns (Dijkstra, Topological Sort) don't have a clean, freely-accessible Easy problem on LeetCode; rather than mislabel a Medium as Easy, those sections say so explicitly instead.

* * *

## How to use this article

Ask what the data looks like, then match it to a family of patterns:

![DSA pattern visualization 1](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-1.png align="center")

* * *

# The 25 Patterns

```plaintext
1.  Two Pointers
2.  Fast & Slow Pointers
3.  Sliding Window
4.  Prefix Sum
5.  HashMap
6.  Stack
7.  Queue
8.  Sorting
9.  Binary Search
10.  Merge Intervals
11.  Bitwise Operations
12.  Heap / Priority Queue
13.  Top K Elements
14.  K-Way Merge
15.  Trees & Tree Traversals
16.  Depth First Search — DFS
17.  Breadth First Search — BFS
18.  Graphs
19.  Greedy
20.  Trie
21.  Topological Sort
22.  Dijkstra's Algorithm
23.  Dynamic Programming — 1D
24.  Dynamic Programming — 2D / Grid
25.  Backtracking
```

* * *

# 1\. Two Pointers

## Motivation

Two Pointers is one of the most important techniques for arrays, strings, and linked structures. Instead of repeatedly examining every pair of elements, we maintain two positions and move them according to a rule. The pattern is particularly powerful when the data is sorted, when we need to compare elements from opposite ends, or when we need to maintain a relationship between two positions. Many O(n²) brute-force solutions become O(n) with the correct pointer movement.

## Visualization

![DSA pattern visualization 2](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-2.png align="center")

## Pseudocode

```plaintext
left = 0
right = n - 1

while left < right:
    evaluate(left, right)

    if condition says move left:
        left++
    else:
        right--
```

## Example

Find whether a sorted array contains two numbers whose sum equals `target`.

```plaintext
left = 0
right = n - 1

while left < right:
    sum = nums[left] + nums[right]
    if sum == target:
        return true
    if sum < target:
        left++
    else:
        right--

return false
```

For `nums = [1, 2, 4, 7, 11]`, `target = 9`:

Start with `1 + 11 = 12` → too large → move `right`. Then `1 + 7 = 8` → too small → move `left`. Then `2 + 7 = 9` → found.

## Real-world application

Two pointers appear in comparing sorted datasets, merging streams, finding matching ranges, memory-efficient array processing, removing duplicates in-place, and partitioning data.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) |
| Medium | [3Sum](https://leetcode.com/problems/3sum/) |
| Medium | [Container With Most Water](https://leetcode.com/problems/container-with-most-water/) |
| Hard | [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) |

* * *

# 2\. Fast & Slow Pointers

## Motivation

Fast and Slow Pointers are designed for situations where you need to detect cycles, find the middle of a linked list, or reason about repeated states without storing every visited position. One pointer moves faster than the other. If a cycle exists, the faster pointer eventually catches the slower pointer. This eliminates extra memory and often turns a problem requiring a visited set into an O(1)-space solution.

## Visualization

![DSA pattern visualization 3](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-3.png align="center")

## Pseudocode

```plaintext
slow = head
fast = head

while fast != null and fast.next != null:
    slow = slow.next
    fast = fast.next.next

    if slow == fast:
        return true

return false
```

## Example

For `1 → 2 → 3 → 4 → 5`: slow moves one node at a time, fast moves two. When fast reaches the end, slow sits at `3` — the middle of the list.

## Real-world application

Cycle detection, linked-list processing, detecting repeated states, circular buffers, and algorithms involving periodic sequences.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/) |
| Medium | [Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) |
| Medium | [Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) |
| Hard | [Longest Duplicate Substring](https://leetcode.com/problems/longest-duplicate-substring/) |

> **Note:** Fast/Slow Pointer is predominantly an Easy/Medium pattern on LeetCode. The Hard problem above leans on a different, string-hashing style of repeated-state reasoning rather than the classic two-pointer cycle walk — don't expect every Hard linked-list problem to use the exact same pointer movement.

* * *

# 3\. Sliding Window

## Motivation

Sliding Window is the natural pattern whenever a problem asks about a **contiguous** portion of an array or string. Instead of recalculating every possible subarray, maintain a window `[left, right]` and update it incrementally. When the current window violates a constraint, move `left`. When it remains valid, expand `right`. This often converts O(n²) substring or subarray enumeration into O(n).

## Visualization

![DSA pattern visualization 4](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-4.png align="center")

## Pseudocode

```plaintext
left = 0

for right in range(n):
    add nums[right] to window

    while window is invalid:
        remove nums[left]
        left++

    update answer
```

## Example

Longest substring without repeating characters, `s = "abcabcbb"`:

Expand: `a`, `ab`, `abc`. The next `a` creates a duplicate, so shrink from the left until the window is valid again. The maximum length is `3`.

## Real-world application

Network traffic monitoring, rate limiting, log analysis, time-series analytics, streaming data, and substring searches.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Maximum Average Subarray I](https://leetcode.com/problems/maximum-average-subarray-i/) |
| Medium | [Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) |
| Medium | [Permutation in String](https://leetcode.com/problems/permutation-in-string/) |
| Hard | [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) |

* * *

# 4\. Prefix Sum

## Motivation

Prefix Sum avoids repeated summation. If a problem repeatedly asks for the sum of a range, calculate cumulative information once and answer each range query in O(1). The deeper lesson: many problems become easier when you transform raw data into cumulative state. Prefix sums also combine extremely well with HashMaps, turning many subarray problems from quadratic into linear time.

## Visualization

![DSA pattern visualization 5](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-5.png align="center")

## Pseudocode

```plaintext
prefix[0] = 0

for i in range(n):
    prefix[i + 1] = prefix[i] + nums[i]

rangeSum(l, r) = prefix[r + 1] - prefix[l]
```

## Example

`nums = [2, 4, 3, 5]` → prefix = `[0, 2, 6, 9, 14]`.

Sum from index `1` to `3` = `prefix[4] - prefix[1] = 14 - 2 = 12`.

## Real-world application

Financial cumulative totals, image processing, range analytics, database aggregation, frequency counting, and time-series calculations.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Running Sum of 1d Array](https://leetcode.com/problems/running-sum-of-1d-array/) |
| Medium | [Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) |
| Medium | [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) |
| Hard | [Maximum Sum of 3 Non-Overlapping Subarrays](https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) |

* * *

# 5\. HashMap

## Motivation

HashMaps are the answer whenever a problem asks you to remember something and retrieve it quickly. Instead of repeatedly scanning an array, store information in a hash table and achieve average O(1) lookup. HashMaps are powerful for frequency counting, complement searching, grouping, duplicate detection, and tracking previously seen states.

## Visualization

![DSA pattern visualization 6](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-6.png align="center")

## Pseudocode

```plaintext
map = {}

for item in data:
    if item exists in map:
        use stored information
    map[item] = updated information
```

## Example

Two Sum, `nums = [2,7,11,15]`, `target = 9`. At `2`, we need `7` → store `2 → index 0`. At `7`, we need `2` → it already exists → answer `[0,1]`.

## Real-world application

Caching, database indexing, frequency analysis, deduplication, lookup services, and session management.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Two Sum](https://leetcode.com/problems/two-sum/) |
| Medium | [Group Anagrams](https://leetcode.com/problems/group-anagrams/) |
| Medium | [Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) |
| Hard | [Substring with Concatenation of All Words](https://leetcode.com/problems/substring-with-concatenation-of-all-words/) |

* * *

# 6\. Stack

## Motivation

A Stack represents **Last In, First Out** behavior. It appears whenever the most recently opened, created, or processed item must be handled first — parentheses matching, expression evaluation, undo operations, browser history, and monotonic-stack problems all depend on stack-like reasoning. The important extension is the **Monotonic Stack**, which maintains increasing or decreasing values to efficiently answer "next greater/smaller" questions.

## Visualization

![DSA pattern visualization 7](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-7.png align="center")

## Pseudocode

```plaintext
stack = []

for item in data:
    while stack is not empty and condition(stack.top, item):
        process(stack.pop())

    stack.push(item)
```

## Example

Valid parentheses `([{}])`: every closing bracket must match the most recently opened bracket, which is exactly what a stack tracks.

## Real-world application

Undo/redo, browser navigation, compiler parsing, expression evaluation, call stacks, and next-event processing.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) |
| Medium | [Min Stack](https://leetcode.com/problems/min-stack/) |
| Medium | [Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) |
| Hard | [Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/) |

* * *

# 7\. Queue

## Motivation

A Queue represents **First In, First Out** behavior — the natural structure for processing things in arrival order. Queues become especially important combined with BFS, where each layer of a graph or tree is processed before moving deeper. Deques (double-ended queues) allow insertion and removal from both ends and enable techniques such as Sliding Window Maximum.

## Visualization

![DSA pattern visualization 8](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-8.png align="center")

## Pseudocode

```plaintext
queue.push(start)

while queue is not empty:
    current = queue.popFront()
    process(current)

    for next in current.neighbors:
        queue.push(next)
```

## Example

People entering a service queue `A → B → C`: A is processed first, then B, then C.

## Real-world application

Job scheduling, print queues, request processing, BFS, message brokers, and customer service systems.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Number of Recent Calls](https://leetcode.com/problems/number-of-recent-calls/) |
| Medium | [Design Circular Queue](https://leetcode.com/problems/design-circular-queue/) |
| Medium | [Rotting Oranges](https://leetcode.com/problems/rotting-oranges/) |
| Hard | [Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) |

* * *

# 8\. Sorting

## Motivation

Sorting transforms an unstructured problem into an ordered one. Once elements are sorted, duplicate detection, interval processing, two-pointer techniques, greedy decisions, and binary search often become possible. Understand not just how library sorting works, but the fundamental ideas behind Merge Sort, Quick Sort, Heap Sort, Counting Sort, and partitioning.

## Visualization

![DSA pattern visualization 9](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-9.png align="center")

## Pseudocode

```plaintext
mergeSort(array):
    if size <= 1:
        return array

    left = mergeSort(left half)
    right = mergeSort(right half)

    return merge(left, right)
```

## Example

`[5, 2, 8, 1]` → split into `[5,2] [8,1]` → sort into `[2,5] [1,8]` → merge into `[1,2,5,8]`.

## Real-world application

Database `ORDER BY`, ranking systems, report generation, scheduling, deduplication, and search preprocessing.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) |
| Medium | [Sort Colors](https://leetcode.com/problems/sort-colors/) |
| Medium | [Sort an Array](https://leetcode.com/problems/sort-an-array/) |
| Hard | [Reverse Pairs](https://leetcode.com/problems/reverse-pairs/) |

* * *

# 9\. Binary Search

## Motivation

Binary Search is not simply "searching a sorted array." Its real power is **eliminating half the search space whenever a condition is monotonic**. This means Binary Search applies to arrays, answer spaces, capacities, speeds, times, and many optimization problems. The key question: "Can I determine which half cannot contain the answer?"

## Visualization

![DSA pattern visualization 10](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-10.png align="center")

## Pseudocode

```plaintext
left = low
right = high

while left <= right:
    mid = left + (right - left) / 2

    if found:
        return mid

    if target belongs to left half:
        right = mid - 1
    else:
        left = mid + 1

return -1
```

## Example

`nums = [1,3,5,7,9]`, `target = 7`. Check `5` → too small, discard left half. Check `7` → found.

## Real-world application

Database indexes, filesystem searches, capacity planning, finding minimum feasible resources, and optimization problems.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Binary Search](https://leetcode.com/problems/binary-search/) |
| Medium | [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) |
| Medium | [Koko Eating Bananas](https://leetcode.com/problems/koko-eating-bananas/) |
| Hard | [Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) |

* * *

# 10\. Merge Intervals

## Motivation

Whenever data represents ranges — meetings, bookings, reservations, time periods, memory regions — think in intervals. The key idea is usually to sort intervals by their starting point and then process them left to right. Once sorted, overlapping intervals become easy to identify because the next interval can only interact with the current merged interval.

## Visualization

![DSA pattern visualization 11](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-11.png align="center")

## Pseudocode

```plaintext
sort intervals by start
result = []

for interval in intervals:
    if result is empty or interval.start > result.last.end:
        result.append(interval)
    else:
        result.last.end = max(result.last.end, interval.end)

return result
```

## Example

`[1,3] [2,6] [8,10] [15,18]` → first two overlap into `[1,6]`.

Final result: `[1,6], [8,10], [15,18]`.

## Real-world application

Calendar scheduling, reservation systems, CPU scheduling, network maintenance windows, and resource allocation.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Summary Ranges](https://leetcode.com/problems/summary-ranges/) |
| Medium | [Merge Intervals](https://leetcode.com/problems/merge-intervals/) |
| Medium | [Insert Interval](https://leetcode.com/problems/insert-interval/) |
| Hard | [The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/) |

> **Note:** LeetCode's cleanest Easy interval-merge problems (Meeting Rooms, Meeting Rooms II) are Premium-only. Summary Ranges is the free Easy substitute — it's a step removed from overlapping-interval merging (it groups consecutive *integers* into ranges rather than merging overlapping *intervals*), but it exercises the same left-pointer/right-pointer range-building instinct. The Skyline Problem is a free Hard problem that leans on the interval sweep-line idea, coordinating many overlapping ranges at once.

* * *

# 11\. Bitwise Operations

## Motivation

Bitwise operations manipulate the individual binary bits of integers. A small set of operations — AND, OR, XOR, NOT, left shift, right shift — solves a surprising number of problems. XOR is particularly important because `x ^ x = 0` and `x ^ 0 = x`. Bit manipulation can produce extremely efficient solutions for parity, masks, subsets, state representation, and duplicate cancellation.

## Visualization

![DSA pattern visualization 12](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-12.png align="center")

## Pseudocode

```plaintext
# Check bit
(n & (1 << k)) != 0

# Set bit
n = n | (1 << k)

# Clear bit
n = n & ~(1 << k)

# XOR matching pairs
answer = 0
for x in nums:
    answer = answer ^ x
```

## Example

Find the single number in `[4,1,2,1,2]`: XOR everything. Since `1^1=0` and `2^2=0`, the result is `4`.

## Real-world application

Permissions, feature flags, network masks, compression, cryptography primitives, and compact state representation.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Single Number](https://leetcode.com/problems/single-number/) |
| Medium | [Counting Bits](https://leetcode.com/problems/counting-bits/) |
| Medium | [Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) |
| Hard | [Triples with Bitwise AND Equal To Zero](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/) |

* * *

# 12\. Heap / Priority Queue

## Motivation

A Heap is useful when you repeatedly need the smallest or largest element while the rest of the data stays unsorted. A sorted array requires expensive updates; a heap provides efficient insertion and removal of the current min/max. Priority Queues are essential for scheduling, Top K problems, Dijkstra, streaming medians, and resource allocation. Key question: "Do I repeatedly need the best current candidate?"

## Visualization

![DSA pattern visualization 13](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-13.png align="center")

## Pseudocode

```plaintext
heap = empty

for value in data:
    push(heap, value)

while heap is needed:
    best = popMin(heap)
    process(best)
```

## Example

Tasks `A→priority 3, B→priority 1, C→priority 2`. A priority queue returns them in order: `B, C, A`.

## Real-world application

CPU scheduling, network packet prioritization, hospital triage, event simulation, task queues, and shortest-path algorithms.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Last Stone Weight](https://leetcode.com/problems/last-stone-weight/) |
| Medium | [Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) |
| Medium | [Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) |
| Hard | [Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) |

* * *

# 13\. Top K Elements

## Motivation

Top K problems ask for only a small number of extreme elements rather than a fully sorted dataset. Sorting everything costs O(n log n), but if `k` is small, a heap can maintain only the best K candidates. The question is not "how do I sort the array?" but "how do I keep only the K elements that matter?"

## Visualization

![DSA pattern visualization 14](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-14.png align="center")

## Pseudocode

```plaintext
minHeap = empty

for value in data:
    push(minHeap, value)

    if heap.size > k:
        popMin(minHeap)

return minHeap
```

## Example

`nums = [3,2,1,5,6,4]`, `k = 2` → maintain only two largest values → result `5, 6`.

## Real-world application

Top search results, most popular products, highest salaries, most frequent events, recommendation systems, and ranking.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/) |
| Medium | [Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) |
| Medium | [Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) |
| Hard | [Sliding Window Median](https://leetcode.com/problems/sliding-window-median/) |

* * *

# 14\. K-Way Merge

## Motivation

K-Way Merge extends the classic two-array merge to many already-sorted sequences. The challenge is repeatedly identifying the smallest current element across K sources. A Min Heap makes this efficient: keep one candidate from each source, remove the smallest, then insert the next element from that same source.

## Visualization

![DSA pattern visualization 15](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-15.png align="center")

## Pseudocode

```plaintext
heap = first element from each sorted list

while heap is not empty:
    value, source = popMin(heap)
    output value

    if source has next element:
        push(heap, next value from source)
```

## Example

`A=[1,4,7] B=[2,5,8] C=[3,6,9]`. Heap starts with `1,2,3`. Remove `1`, insert `4` → heap becomes `2,3,4`. Continue until all elements are merged.

## Real-world application

Merging database partitions, external sorting, log aggregation, merging sorted files, and distributed systems.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) |
| Medium | [Kth Smallest Element in a Sorted Matrix](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/) |
| Medium | [Find K Pairs with Smallest Sums](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/) |
| Hard | [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) |

* * *

# 15\. Trees & Tree Traversals

## Motivation

Trees introduce hierarchical data. The most important skill is systematically visiting every node. The three classic DFS traversals are Preorder, Inorder, and Postorder; BFS provides Level Order traversal. Once traversal is automatic, many tree problems reduce to deciding what information should flow from a child to its parent.

## Visualization

![DSA pattern visualization 16](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-16.png align="center")

## Pseudocode

```plaintext
inorder(node):
    if node == null:
        return
    inorder(node.left)
    process(node)
    inorder(node.right)

preorder(node):
    if node == null:
        return
    process(node)
    preorder(node.left)
    preorder(node.right)

postorder(node):
    if node == null:
        return
    postorder(node.left)
    postorder(node.right)
    process(node)
```

## Example

```plaintext
      4
     / \
    2   6
```

Inorder: `2 4 6`. Preorder: `4 2 6`. Postorder: `2 6 4`.

## Real-world application

Filesystem hierarchies, organizational structures, HTML DOM, expression trees, and database indexes.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) |
| Medium | [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) |
| Medium | [Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/) |
| Hard | [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) |

* * *

# 16\. Depth First Search — DFS

## Motivation

DFS explores one path as deeply as possible before backtracking. It's natural for trees, graphs, connected components, maze problems, and recursive state exploration. The most important DFS skill isn't memorizing recursion — it's identifying what information should be carried through the recursive call.

## Visualization

![DSA pattern visualization 17](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-17.png align="center")

## Pseudocode

```plaintext
DFS(node):
    if node is invalid or visited:
        return

    mark node visited
    process(node)

    for neighbor in node.neighbors:
        DFS(neighbor)
```

## Example

```plaintext
    A
   / \
  B   C
 / \
D   E
```

DFS could visit: `A → B → D → E → C`.

## Real-world application

Maze solving, dependency exploration, connected components, file traversal, cycle detection, and path exploration.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) |
| Medium | [Number of Islands](https://leetcode.com/problems/number-of-islands/) |
| Medium | [Clone Graph](https://leetcode.com/problems/clone-graph/) |
| Hard | [Word Search II](https://leetcode.com/problems/word-search-ii/) |

* * *

# 17\. Breadth First Search — BFS

## Motivation

BFS explores a graph or tree **level by level**, making it the natural algorithm for shortest paths in unweighted graphs, minimum number of moves, and level-order tree traversal. BFS first processes everything one step away, then everything two steps away, and so on — which gives it its shortest-path guarantee when every edge has equal cost.

## Visualization

![DSA pattern visualization 18](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-18.png align="center")

## Pseudocode

```plaintext
queue = [start]
visited = {start}

while queue:
    current = queue.popFront()
    process(current)

    for neighbor in current.neighbors:
        if neighbor not in visited:
            visited.add(neighbor)
            queue.push(neighbor)
```

## Example

`A→B, A→C, B→D, C→E`. BFS visits: `A`, then `B C`, then `D E` — one level at a time.

## Real-world application

Shortest route in unweighted networks, social-network degrees of separation, minimum moves in games, web crawling, and broadcasting.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Minimum Depth of Binary Tree](https://leetcode.com/problems/minimum-depth-of-binary-tree/) |
| Medium | [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) |
| Medium | [Rotting Oranges](https://leetcode.com/problems/rotting-oranges/) |
| Hard | [Word Ladder](https://leetcode.com/problems/word-ladder/) |

* * *

# 18\. Graphs

## Motivation

Graphs model relationships rather than simple sequences or hierarchies. Roads connect cities, users connect to friends, services connect through dependencies, computers connect through networks. The most important graph skill is understanding representation — usually an adjacency list — then choosing the correct traversal or algorithm.

## Visualization

![DSA pattern visualization 19](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-19.png align="center")

## Pseudocode

```plaintext
build adjacency list

visited = {}

DFS/BFS(start):
    mark start visited

    for neighbor in graph[start]:
        if neighbor not visited:
            visit neighbor
```

## Example

```plaintext
A -- B
|    |
C -- D
```

Adjacency list: `A: B,C`, `B: A,D`, `C: A,D`, `D: B,C`.

## Real-world application

Social networks, computer networks, maps, recommendation systems, dependency graphs, and microservice architecture.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Find Center of Star Graph](https://leetcode.com/problems/find-center-of-star-graph/) |
| Medium | [Clone Graph](https://leetcode.com/problems/clone-graph/) |
| Medium | [Number of Provinces](https://leetcode.com/problems/number-of-provinces/) |
| Hard | [Critical Connections in a Network](https://leetcode.com/problems/critical-connections-in-a-network/) |

* * *

# 19\. Greedy

## Motivation

Greedy algorithms make the best-looking choice **right now**, hoping a sequence of locally optimal decisions produces a globally optimal answer. The important skill is recognizing when this is actually valid — usually via an exchange argument or an invariant showing the current best choice can't hurt the final answer. Greedy problems frequently involve intervals, jumps, scheduling, resource allocation, and optimization.

## Visualization

![DSA pattern visualization 20](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-20.png align="center")

## Pseudocode

```plaintext
sort or organize candidates
answer = initial state

for candidate in candidates:
    if choosing candidate is provably safe:
        choose candidate
        update answer

return answer
```

## Example

Jump Game, `nums = [2,3,1,1,4]`: track the furthest reachable index, `maxReach = max(maxReach, i + nums[i])`. If `maxReach` reaches the final index, the destination is reachable.

## Real-world application

Scheduling, resource allocation, compression, routing, task selection, and bandwidth allocation.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Assign Cookies](https://leetcode.com/problems/assign-cookies/) |
| Medium | [Jump Game](https://leetcode.com/problems/jump-game/) |
| Medium | [Gas Station](https://leetcode.com/problems/gas-station/) |
| Hard | [Candy](https://leetcode.com/problems/candy/) |

* * *

# 20\. Trie

## Motivation

A Trie is a tree designed specifically for strings. Instead of comparing entire words repeatedly, it stores characters along paths, making prefix operations extremely efficient. Useful whenever a problem asks about prefixes, autocomplete, dictionaries, or searching many words simultaneously.

## Visualization

![DSA pattern visualization 21](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-21.png align="center")

## Pseudocode

```plaintext
insert(word):
    node = root

    for char in word:
        if char not in node.children:
            node.children[char] = new Node()
        node = node.children[char]

    node.isWord = true

search(word):
    node = root

    for char in word:
        if char not in node.children:
            return false
        node = node.children[char]

    return node.isWord
```

## Example

Insert `cat`, `car`, `can` → they share `ca`, then branch into `t`, `r`, `n`.

## Real-world application

Autocomplete, spell checkers, search suggestions, dictionaries, prefix filtering, and IP routing concepts.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/) |
| Medium | [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) |
| Medium | [Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) |
| Hard | [Word Search II](https://leetcode.com/problems/word-search-ii/) |

* * *

# 21\. Topological Sort

## Motivation

Topological Sort solves ordering problems where dependencies exist: if task B depends on task A, A must appear before B. The underlying structure must be a Directed Acyclic Graph. Two major approaches: DFS postorder, and Kahn's Algorithm using indegrees and a queue. Appears constantly in course scheduling, build systems, package managers, workflow engines, and deployment pipelines.

## Visualization

![DSA pattern visualization 22](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-22.png align="center")

## Pseudocode

```plaintext
calculate indegree of every node
queue = all nodes with indegree 0
order = []

while queue:
    node = queue.pop()
    order.append(node)

    for neighbor in graph[node]:
        indegree[neighbor]--

        if indegree[neighbor] == 0:
            queue.push(neighbor)

if len(order) < n:
    return "cycle exists"

return order
```

## Example

`A→B, A→C, B→D, C→D`. Valid order: `A → B → C → D` (or `A → C → B → D`).

## Real-world application

Package installation, build systems, workflow engines, CI/CD pipelines, course prerequisites, and job dependencies.

## Practice

> **Note on difficulty:** LeetCode's cleanest Topological Sort problems start at Medium — [Find Eventual Safe States](https://leetcode.com/problems/find-eventual-safe-states/) is sometimes mistaken for Easy but is listed as Medium. This set is Medium-heavy for the same reason as Dijkstra above. The classic Hard pick, Alien Dictionary, is Premium-only, so this set uses a free Hard problem instead.

| Difficulty | Problem |
| --- | --- |
| Medium | [Course Schedule](https://leetcode.com/problems/course-schedule/) |
| Medium | [Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) |
| Hard | [Parallel Courses III](https://leetcode.com/problems/parallel-courses-iii/) |

* * *

# 22\. Dijkstra's Algorithm

## Motivation

Dijkstra solves the shortest-path problem when edges have non-negative weights. The fundamental idea is greedy: repeatedly finalize the currently closest unprocessed node. A priority queue makes this efficient. Dijkstra connects theoretical DSA with real systems such as GPS navigation, network routing, and infrastructure optimization. Remember: standard Dijkstra requires **non-negative edge weights**.

## Visualization

![DSA pattern visualization 23](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-23.png align="center")

## Pseudocode

```plaintext
distance[start] = 0
all other distances = infinity
heap = [(0, start)]

while heap:
    dist, node = popMin(heap)

    if dist != distance[node]:
        continue

    for neighbor, weight in graph[node]:
        newDist = dist + weight

        if newDist < distance[neighbor]:
            distance[neighbor] = newDist
            push(heap, (newDist, neighbor))

return distance
```

## Example

`A --2--> B`, `A --5--> C`, `B --1--> C`. From A: `B=2, C=5`. From B: `C=3`. Shortest `A → B → C = 3`.

## Real-world application

GPS navigation, network routing, delivery optimization, telecom routing, and game pathfinding.

## Practice

> **Note on difficulty:** LeetCode does not currently have a clean, freely-accessible Easy problem that requires Dijkstra specifically — the closest fits are Medium. Rather than mislabel one, this set is deliberately Medium-heavy.

| Difficulty | Problem |
| --- | --- |
| Medium | [Network Delay Time](https://leetcode.com/problems/network-delay-time/) |
| Medium | [Path With Minimum Effort](https://leetcode.com/problems/path-with-minimum-effort/) |
| Medium | [Cheapest Flights Within K Stops](https://leetcode.com/problems/cheapest-flights-within-k-stops/) |
| Hard | [Swim in Rising Water](https://leetcode.com/problems/swim-in-rising-water/) |

* * *

# 23\. Dynamic Programming — 1D

## Motivation

Dynamic Programming is used when a problem has **overlapping subproblems** and **optimal substructure**. Instead of solving the same smaller problem repeatedly, store its answer and reuse it. In 1D DP, the state often depends on one or a few previous states. The biggest conceptual shift: stop thinking recursively about every possibility, and instead ask, "What is the smallest piece of information I need to remember to solve the future?"

## Visualization

![DSA pattern visualization 24](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-24.png align="center")

## Pseudocode

```plaintext
dp[0] = base case

for i in range(1, n):
    dp[i] = best(dp[previous states])

return dp[n - 1]
```

## Example

House Robber, `money = [2,7,9,3,1]`. At each house: skip it, or rob it plus the best result from two houses ago.

```plaintext
dp[i] = max(dp[i-1], dp[i-2] + money[i])
```

## Real-world application

Financial optimization, resource allocation, scheduling, sequence optimization, and decision systems.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) |
| Medium | [House Robber](https://leetcode.com/problems/house-robber/) |
| Medium | [Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) |
| Hard | [Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) |

* * *

# 24\. Dynamic Programming — 2D / Grid

## Motivation

Two-dimensional DP is the natural extension when the answer depends on two dimensions — row and column, two strings, two sequences, or two independent states. Grid problems often have a very clean recurrence because each cell depends on neighboring cells. The critical skill is defining exactly what `dp[i][j]` means before writing any recurrence.

## Visualization

![DSA pattern visualization 25](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-25.png align="center")

## Pseudocode

```plaintext
dp[0][0] = starting value

for i in rows:
    for j in columns:
        dp[i][j] = best(
            dp[i - 1][j],
            dp[i][j - 1]
        ) + current

return dp[m - 1][n - 1]
```

## Example

```plaintext
1 3
2 4
```

Minimum path sum `1 → 2 → 4 = 7`, via `dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])`.

## Real-world application

Route optimization, image processing, text comparison, DNA sequence comparison, and robot navigation.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Unique Paths](https://leetcode.com/problems/unique-paths/) |
| Medium | [Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) |
| Medium | [Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) |
| Hard | [Edit Distance](https://leetcode.com/problems/edit-distance/) |

* * *

# 25\. Backtracking

## Motivation

Backtracking is systematic brute force. Instead of blindly generating every possibility, construct a solution incrementally. When a partial solution can no longer lead to a valid answer, immediately undo the decision and try another. Especially powerful for permutations, combinations, subsets, puzzles, constraint satisfaction, and board problems. The three operations to master: **choose, explore, unchoose**.

## Visualization

![DSA pattern visualization 26](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-26.png align="center")

## Pseudocode

```plaintext
backtrack(state):
    if solution is complete:
        save solution
        return

    for choice in choices:
        make choice
        backtrack(new state)
        undo choice
```

## Example

Generate subsets of `[1,2]`: choose `1` → choose `2` → `[1,2]` → undo `2` → undo `1` → explore `[2]`. Results: `[], [1], [2], [1,2]`.

## Real-world application

Puzzle solving, scheduling possibilities, configuration generation, password/key-space exploration, constraint satisfaction, and game search.

## Practice

| Difficulty | Problem |
| --- | --- |
| Easy | [Letter Case Permutation](https://leetcode.com/problems/letter-case-permutation/) |
| Medium | [Subsets](https://leetcode.com/problems/subsets/) |
| Medium | [Combination Sum](https://leetcode.com/problems/combination-sum/) |
| Hard | [N-Queens](https://leetcode.com/problems/n-queens/) |

* * *

# Final Cheat Sheet

| # | Pattern | Main Idea |
| --- | --- | --- |
| 1 | Two Pointers | Move two indexes intelligently |
| 2 | Fast & Slow Pointers | Detect cycles / relative positions |
| 3 | Sliding Window | Maintain a valid contiguous range |
| 4 | Prefix Sum | Precompute cumulative information |
| 5 | HashMap | O(1)-average lookup and frequency tracking |
| 6 | Stack | LIFO / nested / monotonic processing |
| 7 | Queue | FIFO / level-by-level processing |
| 8 | Sorting | Create order that enables simpler logic |
| 9 | Binary Search | Eliminate half the search space |
| 10 | Merge Intervals | Sort and combine overlapping ranges |
| 11 | Bitwise | Manipulate binary state efficiently |
| 12 | Heap | Repeatedly access min/max |
| 13 | Top K | Keep only the K candidates that matter |
| 14 | K-Way Merge | Merge multiple sorted sources |
| 15 | Trees | Hierarchical traversal |
| 16 | DFS | Explore deeply |
| 17 | BFS | Explore level by level |
| 18 | Graphs | Model relationships with nodes and edges |
| 19 | Greedy | Make provably safe local choices |
| 20 | Trie | Efficient prefix/string operations |
| 21 | Topological Sort | Order dependency graphs |
| 22 | Dijkstra | Shortest path with non-negative weights |
| 23 | 1D DP | Reuse previous optimal states |
| 24 | 2D DP | State depends on two dimensions |
| 25 | Backtracking | Choose → explore → undo |

# The Real DSA Skill

The objective is **not**: "I solved these 100 LeetCode problems."

The objective is: "I can recognize which pattern this problem belongs to."

![DSA pattern visualization 27](https://static.sibansal.dev/the-only-25-patterns-you-need-to-master-dsa/25-DSA-patterns-27.png align="center")

Master these 25 patterns deeply, and DSA stops being a collection of thousands of unrelated questions. It becomes a relatively small set of ideas that keep appearing in different disguises.

## One final rule

Do not move to the next pattern after merely watching its solution. For every pattern:

1.  Understand the brute-force solution.
    
2.  Understand why it is too slow.
    
3.  Identify the pattern.
    
4.  Implement the pattern from memory.
    
5.  Solve the Easy problem without help.
    
6.  Solve both Medium problems.
    
7.  Attempt the Hard problem.
    
8.  Revisit the pattern after one week.
    
9.  Solve one unseen problem using the same pattern.
    

That is how you turn **pattern recognition into interview skill**.

## 🎯 Practice the 25 DSA Patterns

Reading about patterns is only the first step. The real progress comes from solving problems, revisiting patterns, and tracking what you can solve independently.

I created a **Notion template** to help you practice all 25 patterns in one place.

### What's inside?

*   ✅ All **25 DSA patterns** organized in one dashboard
    
*   📊 Pattern-by-pattern mastery tracking
    
*   🧠 Main idea for each pattern
    
*   🔄 Track your progress from **Not Started → Learning → Practicing → Mastered**
    
*   📝 A dedicated space to practice and review problems
    
*   🎯 Built around the same pattern-recognition approach used in this article
    

### 👉 [Get the Free DSA Mastery 25 Notion Template](https://app.notion.com/p/3b9b019b7a298043b776e0523a10b9a1?v=2ca03d048de34d3890c97ba0197ec3fc&source=copy_link)

> **Don't just solve more problems. Learn to recognize the pattern behind them.**
