Stop memorising disconnected LeetCode questions. Every coding interview problem is governed by one of 30 core algorithmic patterns. Master the triggers, derive the invariants, eliminate repeated work, and write verified solutions in C++20, Java 21, Python 3.12, and TypeScript.
Instead of reading a prompt blindly, look for algorithmic triggers: sorted array keywords indicate Two Pointers or Binary Search; contiguous window constraints trigger Sliding Window; next greater queries trigger Monotonic Stack.
Brute force solutions evaluate redundant combinations (e.g. O(N²) nested loops). Patterns define a strict state invariant that proves entire regions of the search space cannot contain the answer, collapsing time complexity to O(N) or O(log N).
Algorithms transcend programming syntax. Master core logic with concrete implementations in modern C++20, Java 21, Python 3.12, and TypeScript 5 without language-specific idiosyncrasies clouding your reasoning.
Match problem clues and constraints directly to the optimal algorithmic pattern and time guarantees.
| Problem Clue / Trigger | Pattern | Time | Space | Canonical LeetCode Problems |
|---|---|---|---|---|
| Sorted array, find a pair or triplet summing to target; eliminate O(N²) pair scan | Two Pointers (Opposite Ends) | O(N) | O(1) | Two Sum II, 3Sum, Container With Most Water |
| Contiguous subarray/substring with monotonic condition (e.g. at most K distinct, min window) | Sliding Window | O(N) | O(1) – O(K) | Longest Substring Without Repeating Characters, Minimum Window Substring |
| Find the Next / Previous Greater or Smaller element in linear O(N) time without O(N²) scan | Monotonic Stack | O(N) | O(N) | Daily Temperatures, Next Greater Element, Largest Rectangle in Histogram |
| Linked list cycle detection, find middle node, or palindrome linked list in O(1) space | Fast & Slow Pointers | O(N) | O(1) | Linked List Cycle II, Middle of the Linked List |
| Overlapping intervals, scheduling, merge or insert intervals | Merge Intervals | O(N log N) | O(N) | Merge Intervals, Insert Interval, Non-overlapping Intervals |
| Monotonic search space (minimize max, maximize min, answer is in [low, high]) | Binary Search on Answer | O(log(range) · cost) | O(1) | Koko Eating Bananas, Capacity To Ship Packages |
| Top / Bottom K elements in stream or unsorted collection without full sorting | Top K Elements (Heap) | O(N log K) | O(K) | Kth Largest Element in an Array, Top K Frequent Elements |
| Connected components, dynamic connectivity, cycle detection in undirected graph | Union-Find (Disjoint Set) | O(α(N)) ≈ O(1) | O(N) | Number of Provinces, Redundant Connection |
| Dependency resolution, course prerequisites, build order in DAG | Topological Sort (Kahn's / DFS) | O(V + E) | O(V) | Course Schedule I & II, Alien Dictionary |
| Optimal substructure with overlapping subproblems (choices make state transition) | Dynamic Programming (1D / 2D / Knapsack) | O(states · transitions) | O(states) | Coin Change, Longest Increasing Subsequence, 0/1 Knapsack |
Select any pattern to access full theoretical derivations, visual animated dry-runs, sub-patterns, and problem ladders.
Use a hash map or set to remember what you have already seen, so you never search the array twice.
Keep two indexes into the data and move them toward the answer, throwing away possibilities you can prove are useless.
Keep a current range [left … right] and slide it across the array, updating what you know instead of recomputing it.
Store running totals so the sum of any range becomes one subtraction: sum(l..r) = prefix[r+1] − prefix[l].
If you can answer "is the answer on the left or the right?" in one check, you can halve the search space every step.
Use a stack when the most recent unfinished thing must be handled first — like matching brackets.
Keep a stack that is always sorted. When a new element breaks the order, the popped elements just found their "next greater/smaller".
Sort intervals (usually by start), then walk once — each new interval only needs to be compared with the last one you kept.
When values are 1..n (or 0..n), each value has a "home" index. Swap values home; whatever is out of place is your answer.
Move two pointers at different speeds (or with a fixed gap) to find cycles, middles, and the k-th node from the end in one pass.
Reverse links in place with three pointers (prev, curr, next). Most hard list problems are "reverse a piece, then reconnect".
Process the tree level by level with a queue. Everything about "levels", "rows", or "closest" is BFS.
Solve a tree by asking each child for an answer (recursion), then combine. Decide what each call returns and what it receives.
A tree of characters where each path from the root spells a prefix. Prefix questions become a walk down the tree.
Keep a heap of size K so you always know the K best items without sorting everything.
Split items into a "small half" (max-heap) and a "large half" (min-heap). The tops give you the median instantly.
Merge many sorted lists by keeping only the current front of each list in a min-heap.
Treat grids, words, and states as nodes connected by edges, then explore with BFS (shortest steps) or DFS (reach everything).
Order tasks so every prerequisite comes first. Repeatedly take tasks that have no remaining prerequisites.
Keep groups of connected items; "union" merges two groups and "find" tells you which group an item is in, almost in O(1).
When edges have weights, plain BFS is not enough. Dijkstra always expands the closest unfinished node next.
Build the answer one choice at a time; when a choice leads nowhere, undo it and try the next one.
Make the choice that looks best right now, and prove that this never hurts later choices.
The answer at position i is built from answers at a few earlier positions. Write that rule, then fill left to right.
For each index, keep the best subarray that ends exactly here: extend the previous one or start fresh.
Items with weights; decide for each item whether to take it. dp[capacity] stores the best you can do with that much room.
dp[i] = length of the best increasing chain that ends at i. Faster version: keep the smallest possible tail for each length.
Each cell's answer comes from its neighbours above and to the left. Fill the table row by row.
Compare two strings (or one string with itself) with a table where dp[i][j] describes the first i and j characters.
Work directly with the binary form of numbers: XOR cancels pairs, masks pick bits, shifts multiply/divide by 2.
DSA patterns are reusable algorithmic mental templates that solve entire families of computational problems. Instead of memorising hundreds of distinct LeetCode problems, mastering 30 core patterns—such as Two Pointers, Sliding Window, Monotonic Stack, and Topological Sort—allows you to recognise structural clues in problem statements, formulate invariants, and write optimal solutions in C++, Java, Python, or TypeScript.
Coding interview platforms feature over 3,000 problems, but the underlying algorithmic patterns number fewer than 30. Memorization fails when interviewers introduce minor constraint tweaks. Pattern mastery teaches you the 6-step derivation loop: recognizing the trigger word, identifying brute force repeated work, specifying the state invariant, executing valid transitions, and verifying multi-language code.
Begin with Two Pointers (Opposite Ends and Read-Write pointers), followed immediately by Sliding Window. These patterns establish fundamental intuition about pointer invariants, reducing naive O(N²) nested loops down to optimal O(N) linear time with O(1) auxiliary space.
While both maintain two indices, Two Pointers typically operate on sorted arrays from opposite ends (left and right converging inward) or swap elements in-place. Sliding Window maintains a contiguous subsegment [left, right] where the right pointer expands to incorporate elements and the left pointer shrinks to restore a validity invariant.
Use a Monotonic Stack whenever a problem asks for the 'Next Greater Element', 'Previous Greater Element', 'Stock Span', or optimal bounding bars in histogram rectangles. It maintains elements in strictly increasing or decreasing order, guaranteeing each element is pushed and popped at most once for an amortized O(N) time complexity.
Yes. Every pattern and question on Brute2Best includes verified implementations with full syntax highlighting across C++20, Java 21, Python 3.12, and TypeScript 5, alongside animated visual dry runs.
Stop memorizing random solutions. Learn algorithmic thinking from brute force to the best solution with step-by-step derivations in C++, Java, Python, and TypeScript.