🧩 Pattern Library
Master the patterns that matter. Each pattern includes pseudocode, complexity analysis, recognition signals, and linked practice problems.
Two Pointers
→Use two pointers (usually `left` and `right`) to traverse an array from both ends toward the center, or both from the start at different speeds. Works best on sorted arrays or when you need to find pairs/triplets.
Sliding Window
→Maintain a window (subarray) that slides across the array. Expand or shrink the window to find optimal subarrays that satisfy a condition. Avoids nested loops by reusing computation from the previous window position.
Binary Search
→Repeatedly divide the search space in half. Compare the middle element with the target — if smaller, search the right half; if larger, search the left half. Requires sorted data.
Depth First Search
→Traverse deep into a graph or tree before backtracking. Often implemented using recursion or an explicit stack. Excellent for exploring all paths or finding specific structures like connected components.
Hash Map
→Use a hash map or dictionary to store key-value pairs for O(1) average time complexity lookups.
Stack
→A Last-In-First-Out (LIFO) data structure. Useful for parsing, evaluating expressions, and tracking state that needs to be reversed.
Greedy
→Make the locally optimal choice at each stage with the hope of finding a global optimum. Often requires sorting the input first.
Breadth-First Search
→Explore a graph or tree level by level using a queue. Guarantees finding the shortest path on unweighted graphs.
Graph Traversal
→Traverse and manipulate networks of vertices connected by edges. Common representations include adjacency lists and matrices, explored via Breadth-First or Depth-First search.
Trie (Prefix Tree)
→A tree-like data structure used to store a dynamic set or associative array where the keys are usually strings. Efficient for prefix-based searches and auto-completion.
Heap / Priority Queue
→A specialized tree-based data structure that satisfies the heap property. In a min-heap, the root is the minimum element, enabling O(1) retrieval and O(log N) insertion/deletion.
Dynamic Programming
→Solve complex problems by breaking them down into simpler subproblems, storing results of subproblems to avoid redundant computations (optimal substructure and overlapping subproblems).
Backtracking
→An algorithmic technique that considers searching every possible combination to solve a computational problem. It builds candidates incrementally and abandons (backtracks) a candidate as soon as it cannot lead to a valid solution.