← Back to Data Structures & Algorithms

Data Structures & Algorithms — Quick Summary

Quick revision: every topic, key terms, and mnemonics for Data Structures & Algorithms.


This is a quick revision doc covering all 40 topics in the DSA collection. Open the linked notes if you want depth — this is for fast pre-interview cementing of patterns.

Complexity & Fundamentals

Big O Notation

What it is. A way to describe how runtime / memory grows with input size. We care about growth rate, not constants.

Key terms.

Remember. “Constants Don’t Matter; Big Terms Win.” For n=1B, O(log n) ≈ 30 steps; O(n²) ≈ heat death of the universe.

Recursion

What it is. A function that calls itself with a smaller input until a base case.

Key terms.

Remember. “Base + smaller subproblem.” Russian-doll mental model — open until smallest, then assemble back up.

Bit Manipulation

What it is. Direct work with binary digits — fast and O(1).

Key tricks.

Remember. “XOR = different bits. Pairs cancel.”

Two Pointers

What it is. Two indices traversing data together. Three flavors:

PatternSetupUse
Opposite directionleft=0, right=n-1, move inwardTwo sum (sorted), reverse, palindrome
Same direction (slow/write, fast/read)both forwardRemove duplicates, partition
Fast & slow (Floyd)slow+1, fast+2Cycle detection, find middle

Remember. Sorted array + “find a pair” → two pointers from both ends. O(n) with O(1) space.

Sliding Window

What it is. Maintain a contiguous window over an array/string and slide it.

Two flavors.

Template.

left = 0
for right in range(len(arr)):
    # add arr[right] to state
    while invalid:
        # remove arr[left] from state
        left += 1
    result = best(result, right - left + 1)

Remember. “Contiguous + max/min/longest/shortest” → sliding window. Each element enters and leaves once → amortized O(n).

Arrays, Strings & Hashing

Arrays & Operations

What it is. Contiguous memory; O(1) random access via address arithmetic.

Key terms.

Strings & Pattern Matching

What it is. Strings are arrays of characters. Immutable in JS/Python/Java String → concatenation in a loop is O(n²).

Key idioms.

Hash Maps & Hash Sets

What it is. Hash function maps keys to buckets. Average O(1) insert/lookup/delete.

Key terms.

Remember. “Stuck on a brute-force O(n²) pair check? Try a hash map.”

Prefix Sum & Difference Arrays

What it is.

Remember. “Prefix = fast queries. Difference = fast updates.”

Matrix Problems

What it is. 2D arrays — matrix[row][col]. Stored row-major.

Key patterns.

Sorting Algorithms

What it is. Arranging elements in order.

AlgorithmBestAvgWorstSpaceStable
BubbleO(n)O(n²)O(n²)O(1)yes
SelectionO(n²)O(n²)O(n²)O(1)no
InsertionO(n)O(n²)O(n²)O(1)yes
MergeO(n log n)O(n log n)O(n log n)O(n)yes
QuickO(n log n)O(n log n)O(n²)O(log n)no
HeapO(n log n)O(n log n)O(n log n)O(1)no

Key terms.

Remember. “Sorting is O(n log n), so it’s ‘free’ if your overall algorithm is already O(n log n) or worse.”

Linked Lists, Stacks & Queues

Linked Lists

What it is. Nodes with a value + pointer(s) to other nodes. Singly = next; Doubly = prev + next.

Key terms.

def reverse(head):
    prev, curr = None, head
    while curr:
        nxt = curr.next
        curr.next = prev
        prev, curr = curr, nxt
    return prev

Remember. “prev / curr / next.” Three pointers — every linked-list problem.

Stacks

What it is. LIFO. Push/pop/peek/isEmpty all O(1).

Implementations. JS array, Python list, Java ArrayDeque (avoid legacy java.util.Stack).

Patterns.

Remember. Call stack = function calls; same data structure powers recursion itself.

Monotonic Stack

What it is. Stack kept in sorted order. Each element pushed and popped at most once → amortized O(n).

Cheat sheet.

GoalStack orderDirection
Next greaterDecreasingLeft→right
Next smallerIncreasingLeft→right
Previous greaterDecreasingRight→left
Previous smallerIncreasingRight→left

Classic problems. Next greater element, daily temperatures, largest rectangle in histogram (use 0-sentinel at end).

Queues and Deques

What it is. FIFO queue (enqueue back, dequeue front). Deque allows both ends in O(1).

Implementations. JS array (note: shift is O(n)), Python collections.deque, Java LinkedList/ArrayDeque.

Use cases.

Remember. “BFS = queue. DFS = stack. Sliding window max = monotonic deque.”

Priority Queues and Heaps

What it is. Heap = complete binary tree as an array. Min-heap: parent ≤ children. Max-heap: parent ≥ children.

Key terms.

Patterns.

Remember. “Find Top K → min-heap of size K.” “Sort O(n log n) > Top-K O(n log k) when k is small.”

Data Structure Design Problems

What it is. Build a custom DS with required ops at required complexities.

Key designs.

Remember. “Hash map + doubly linked list = O(1) cache.”

Trees & Tries

Binary Trees

What it is. Each node has up to two children (left, right).

Terminology. Root, leaf, internal, depth (distance from root), height (longest path down to a leaf), subtree.

Traversals.

Common problems. Max depth (1 + max(left, right)), invert tree (swap children recursively), is symmetric (compare mirror), path sum, lowest common ancestor.

Binary Search Trees

What it is. BST property: every left descendant < node < every right descendant. Inorder traversal yields sorted order.

Operations. Search/insert/delete all O(log n) average, O(n) worst (degenerate to linked list — needs balancing for guaranteed log n).

Delete cases.

  1. Leaf — just remove.
  2. One child — replace with child.
  3. Two children — replace with inorder successor (smallest in right subtree), then delete that.

Validate BST. Pass (min, max) bounds down recursively, NOT just node.left.val < node.val.

What it is. Halve search space each step on sorted data. O(log n).

Template.

lo, hi = 0, len(arr) - 1
while lo <= hi:
    mid = lo + (hi - lo) // 2  # avoid overflow
    if arr[mid] == target: return mid
    if arr[mid] < target: lo = mid + 1
    else: hi = mid - 1
return -1

Variants. First/last occurrence; rotated sorted array (find pivot first or compare halves); search for “boundary” where condition flips.

Remember. “lo + (hi - lo) / 2” — overflow-safe. Off-by-one is the #1 bug; pick <= vs < consistently.

Tree Construction and Serialization

What it is. Build trees from traversals or convert to/from strings.

Key facts.

Lowest Common Ancestor

What it is. Deepest node that is ancestor of both p and q.

BST version. If both < root → recurse left; both > root → recurse right; otherwise root is the LCA. O(log n).

General binary tree. Recursive: if root is p or q, return root. Recurse left/right. If both return non-null → root is LCA; else return whichever is non-null. O(n).

Remember. Distance(p, q) = depth(p) + depth(q) - 2 * depth(LCA).

Tries (Prefix Trees)

What it is. Tree where each node = a character. Word = path from root to a node marked isEnd. Children stored as map/array.

Operations. Insert / search word / search prefix — all O(L) where L = word length.

When to use. Autocomplete, spell-check, prefix queries on a dictionary, word games. Replace hash map when prefix queries matter.

Memory. More than a hash set, but shared prefixes save memory and enable prefix iteration.

Graphs

Graph Representations

What it is. Nodes (vertices) + edges. Directed vs undirected, weighted vs unweighted, cyclic vs acyclic.

Two representations.

Adjacency ListAdjacency Matrix
SpaceO(V + E)O(V²)
Edge queryO(degree)O(1)
Best forSparse graphs (most interview Qs)Dense graphs
graph = defaultdict(list)
for u, v in edges:
    graph[u].append(v)
    graph[v].append(u)  # undirected

BFS and DFS

What it is. Two ways to explore a graph.

BFS. Queue. Level-by-level. Shortest path in unweighted graphs. O(V + E). DFS. Stack or recursion. Goes deep first. Path existence, connected components, cycle detection. O(V + E).

def bfs(graph, start):
    visited = {start}
    q = deque([start])
    while q:
        node = q.popleft()
        for nb in graph[node]:
            if nb not in visited:
                visited.add(nb)
                q.append(nb)

Remember. “BFS = ripples (queue). DFS = caves (stack/recursion).”

Topological Sort

What it is. Linear ordering of DAG nodes such that for every edge u→v, u comes before v. Used for dependency resolution (course schedule, build systems).

Two algorithms.

Remember. “DAG only. Cycle → no topo order.”

Shortest Path Algorithms

Decision tree.

Dijkstra in 3 lines. Min-heap of (dist, node). Pop closest, relax neighbors. Skip if popped dist > known dist.

Remember. “BFS for hops. Dijkstra for happy weights. Bellman-Ford for negatives.”

Union-Find (Disjoint Set)

What it is. Track connected components. find(x) returns root of x’s group; union(x, y) merges two groups.

Optimizations.

def find(x):
    if parent[x] != x:
        parent[x] = find(parent[x])  # path compression
    return parent[x]

def union(x, y):
    rx, ry = find(x), find(y)
    if rx == ry: return False
    if rank[rx] < rank[ry]: rx, ry = ry, rx
    parent[ry] = rx
    if rank[rx] == rank[ry]: rank[rx] += 1
    return True

When to use. Streaming connectivity (“is X still connected to Y after these edges?”), Kruskal’s MST, number of connected components, redundant edge detection.

Advanced Graph Problems

Cycle detection (directed). 3-color DFS — white (unseen), gray (in current path), black (done). Gray edge encountered → cycle.

Cycle detection (undirected). DFS with parent — if neighbor visited and not parent → cycle. Or Union-Find: union returns false on existing edge → cycle.

Bipartite check. 2-color BFS — color start, alternate colors per level; conflict → not bipartite.

MST (Minimum Spanning Tree).

Tarjan’s / Kosaraju’s — strongly connected components.

Dynamic Programming

DP Fundamentals

What it is. Solve problem by combining solutions to overlapping subproblems. Two requirements: overlapping subproblems + optimal substructure.

Two approaches.

Naive fib O(2^n) → memoized O(n) → bottom-up O(n) → space-optimized O(1) (rolling variables).

Steps. 1) Define state dp[i] (or dp[i][j]). 2) Recurrence — express dp[i] from prior states. 3) Base cases. 4) Iterate in dependency order.

Remember. “DP = remember answers.” If you’re recomputing the same thing, cache it.

1D DP Patterns

Climbing stairs. dp[i] = dp[i-1] + dp[i-2]. Pure Fibonacci.

House Robber. dp[i] = max(dp[i-1], dp[i-2] + nums[i]) — skip or take.

Coin Change (min coins for target). dp[a] = min(dp[a - coin] + 1 for coin in coins). O(amount × coins).

LIS (Longest Increasing Subsequence). dp[i] = 1 + max(dp[j] for j<i where nums[j]<nums[i]). O(n²). Or O(n log n) with patience sort + binary search.

Word Break. dp[i] = any(dp[j] and s[j:i] in wordSet for j in 0..i).

Decode Ways. Like climbing stairs but with validity checks on 1- and 2-digit substrings.

2D DP Patterns

Unique Paths. dp[i][j] = dp[i-1][j] + dp[i][j-1]. First row/col = 1.

Min Path Sum. dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]).

Longest Common Subsequence.

Edit Distance (Levenshtein). Min operations (insert, delete, replace). If chars match → dp[i-1][j-1]. Else → 1 + min(insert, delete, replace).

Remember. Many 2D DP problems can be space-optimized to 1D (or two rows).

Knapsack Patterns

0/1 Knapsack. Each item used at most once. dp[i][w] = max(skip, take if fits) = max(dp[i-1][w], dp[i-1][w-wt[i]] + val[i]). O(n × W).

Unbounded Knapsack. Can reuse items. Coin Change is unbounded knapsack. dp[w] = max(dp[w-wt[i]] + val[i]) for all items i.

Subset Sum / Partition Equal Subset Sum. Boolean DP: can we reach sum s? dp[s] = dp[s] or dp[s - num].

Target Sum / Counting Subsets. Count ways instead of yes/no.

Remember. “0/1 = take or skip. Unbounded = take or skip-and-stay (don’t advance i).”

Interval and String DP

Pattern. dp[i][j] = answer for substring/range [i..j]. Build from smallest length to largest.

Longest Palindromic Subsequence. If s[i]==s[j]: dp[i+1][j-1] + 2. Else: max(dp[i+1][j], dp[i][j-1]).

Longest Palindromic Substring. Either expand from each center (O(n²)/O(1)) or DP with dp[i][j] = (s[i]==s[j]) and dp[i+1][j-1].

Palindrome Partitioning II (min cuts), Matrix Chain Multiplication — classic interval DP.

Remember. “Length 1 → length 2 → … → length n. Outer loop = length, inner = start index.”

DP on Trees and Graphs

What it is. State per node, computed bottom-up via post-order DFS.

House Robber III. Each node returns (rob_this, skip_this). Rob = val + skip both kids; Skip = max of both for each kid.

Diameter of a Tree. Track longest path through each node = left_height + right_height. Return max(left, right) + 1 upward.

Path Sum III, Longest Univalue Path — same shape: post-order, return one value, accumulate global answer.

For DAGs, use memoization with topological order. Tree DP doesn’t need memo because each subtree is visited once.

Greedy, Backtracking & Interview Patterns

Greedy Algorithms

What it is. Make the locally optimal choice; never reconsider.

When greedy works. Greedy choice property + optimal substructure. Always test with a small counterexample.

Classics.

Remember. “Sort, scan, decide.” If greedy fails, you probably need DP.

Backtracking

What it is. DFS with undo. Try a choice → recurse → undo → try next.

Universal template.

def backtrack(path, choices):
    if goal(path):
        result.append(path[:])  # copy!
        return
    for c in choices:
        if not valid(c, path): continue
        path.append(c)          # choose
        backtrack(path, ...)    # explore
        path.pop()              # un-choose

Classics. Subsets (2^n), Permutations (n!), Combinations C(n,k), N-Queens, Sudoku, Word Search, Combination Sum.

Pruning. Sort + skip duplicates; bound checks; constraint propagation. Pruning is the difference between “elegant” and “TLE”.

Remember. “Choose, explore, un-choose.” Always copy the path on goal hit (not the reference).

Interval Problems

What it is. Problems on [start, end] ranges. Almost always sort by start (sometimes by end) first.

Key trick — overlap. Two intervals [a,b] and [c,d] overlap iff a < d AND c < b.

Classics.

Sweep line technique. Convert each interval to two events (+1 at start, -1 at end), sort, sweep with running counter.

Remember. “Sort by start, then iterate. Two intervals: extend or push.”

Binary Search on Answer

What it is. Binary search the SOLUTION SPACE, not the array. Works when feasibility is monotonic in the answer.

Recognition.

Template. lo, hi = min_possible, max_possible. While lo < hi: mid = (lo+hi)//2. If feasible(mid)hi = mid (try smaller). Else → lo = mid + 1. Return lo.

Classics. Koko Eating Bananas (smallest speed to finish in H hours), Capacity to Ship Within D Days, Split Array Largest Sum, Minimum Pages (book allocation).

Remember. “Define feasible(x). If yes for x, also yes for x+1 → binary searchable.”

Common Interview Patterns Cheatsheet

Pattern → trigger keywords.

PatternTrigger
Two Pointers”sorted”, “pair”, “in-place”, “palindrome”
Sliding Window”subarray”, “substring”, “contiguous”, “longest/shortest with constraint”
Hash Map / Set”frequency”, “count”, “duplicate”, “anagram”, “two sum”
Prefix Sum”subarray sum”, “range sum”, “cumulative”
Binary Search”sorted”, “log n”, “minimize maximum / maximize minimum”
BFS”shortest”, “minimum steps”, “level by level”, “nearest”
DFS”path exists”, “connected”, “island”, “all paths”
DP”how many ways”, “min/max cost”, “can we reach”
Greedy”schedule”, “intervals”, “jump”, “activity”
Backtracking”all combinations”, “all permutations”, “generate all”, “n queens”
Monotonic Stack”next greater/smaller”, “histogram”, “stock span”
Heap / Priority Queue”kth”, “top k”, “merge k sorted”, “median stream”
Trie”prefix”, “autocomplete”, “word search in dictionary”
Union-Find”connected components”, “redundant edge”, “streaming connectivity”
Topological Sort”dependencies”, “course schedule”, “build order”

Big-O Cheatsheet (operations across data structures)

Data StructureAccessSearchInsertDelete
Array (sorted)O(1)O(log n)O(n)O(n)
Array (unsorted)O(1)O(n)O(1) end / O(n) midO(n)
Linked ListO(n)O(n)O(1) given pointerO(1) given pointer
Stack / QueueO(n)O(1)O(1)
Hash Map / SetO(1) avgO(1) avgO(1) avg
BST (balanced)O(log n)O(log n)O(log n)O(log n)
HeapO(1) min/maxO(n)O(log n)O(log n)
TrieO(L)O(L)O(L)O(L)
Union-Find (path compression + rank)~O(1)~O(1)

Remember. “Hash for lookup. Heap for top-K. Trie for prefix. Union-Find for components. Stack for LIFO/parens. Queue for BFS/scheduling.”