Skip to content
Pressentify
Home
Learn
Handbooks
32 print-ready volumes across 6 handbooks
7 volumes
System Design
2 volumes
AWS Production
4 volumes
Python
6 volumes
FastAPI
7 volumes
AI Full-Stack
6 volumes
Django
Topics
14 courses, beginner to production
Python
PostgreSQL
System Design
Django
MongoDB
AWS
AI Full-Stack
Data Structures & Algorithms
JavaScript
React
Docker
FastAPI
Next.js
MySQL
Cheatsheets
8 one-page quick references
Python
PostgreSQL
System Design
Django
MongoDB
AWS
AI Full-Stack
Data Structures & Algorithms
DSA Lab
12 animated lessons, synced to running code
Binary Search
Two Pointers
Maximum Subarray (Kadane’s)
Move Zeroes
Minimum Size Subarray Sum
Roadmap
Study planner
Job hunt
AI Interview
Blog
Sign in
Get started
Cheatsheets
/
Data Structures & Algorithms
Data Structures & Algorithms cheat sheets
14 sheets · 14 sections
Quick reference
Full course
01
How to Think About a Problem
1 sheet
How to Think About a Problem
Restate the problem in your own words
Identify input size and constraints
Work a small example by hand first
Identify the brute-force solution before optimizing
Name the pattern the problem resembles
Consider edge cases
Decide on a data structure before writing code
Trace through your own solution before trusting it
02
Big-O and Complexity Analysis
1 sheet
Big-O and Complexity Analysis
Common complexity classes, in order
Analyzing loops (single, nested, sequential)
Membership check (`in`): list O(n) vs dict/set O(1) average
String concatenation in a loop is O(n²)
Dropping constants and lower-order terms
Time complexity vs space complexity
Reading constraints to guess required complexity
list index/append/pop-from-end: O(1)
list insert/pop/delete at an arbitrary index: O(n)
sorted() / list.sort(): O(n log n), Timsort
03
Arrays and Lists
1 sheet
Arrays and Lists
Prefix sums
Kadane's algorithm (maximum subarray)
Cyclic sort pattern (numbers in range 1..n)
Dutch national flag / 3-way partition
Merging two sorted arrays in place
list.copy() vs assignment (aliasing pitfall)
Difference arrays (range-update trick)
Matrix traversal (row-major, column-major, diagonal, spiral)
Rotating an array (reversal trick)
Negative indexing and slicing (`a[::-1]`, `a[i:j]`)
04
Strings
1 sheet
Strings
Palindrome checks
Anagram checks (via sorting or frequency count)
Basic pattern matching (naive substring search)
`ord()` / `chr()` for character-to-index tricks
Strings as immutable sequences (why in-place edits aren't free)
Building strings efficiently (join vs += in a loop)
Substring vs subsequence (distinction matters a lot)
Character frequency counting
`collections.Counter` for frequency maps
`str.find()` vs manual scanning
05
Hashing — Hash Maps and Sets
1 sheet
Hashing — Hash Maps and Sets
Using a hash map to trade space for time
Two Sum via hash map (canonical example)
Grouping (e.g. group anagrams) via hash map of lists
What a hash function does and why collisions happen
Using a set for "seen before" checks
Using a hash map as a frequency counter
Hashing tuples/frozensets for composite keys
`collections.defaultdict`
`collections.Counter` (`.most_common()`, arithmetic on counters)
Using tuples as dict keys (must be hashable — no lists inside)
06
Two Pointers
1 sheet
Two Pointers
Opposite-direction pointers (start/end converging)
Same-direction pointers (fast/slow at different rates)
Fast/slow pointers for cycle detection (Floyd's algorithm)
Merging two sorted structures with two pointers
Three pointers (e.g. 3Sum built on top of two pointers)
Recognizing when a problem on a sorted array/list is a two-pointer problem in disguise
07
Sliding Window
1 sheet
Sliding Window
Fixed-size window (e.g. max sum of size-k subarray)
Variable-size window that grows/shrinks based on a condition
Window state maintained incrementally (not recomputed each shift)
Longest substring without repeating characters
Minimum window substring
Longest substring with at most K distinct characters
Recognizing "contiguous subarray/substring satisfying X" as a sliding-window signal
08
Recursion
1 sheet
Recursion
Base case and recursive case
The call stack, and how recursion depth relates to space complexity
Recursion on arrays/strings (divide the input, recurse on a piece)
Memoization as the bridge from recursion to dynamic programming
Tracing a recursion tree by hand
Head recursion vs tail recursion (Python doesn't optimize tail calls)
Converting recursion to iteration
Mutual recursion
`functools.lru_cache` for automatic memoization
09
Sorting Algorithms
1 sheet
Sorting Algorithms
Merge sort — O(n log n), stable, extra space
Quicksort — O(n log n) average, O(n²) worst case, in-place
`sorted()` and `list.sort()` — Timsort, stable, O(n log n)
Insertion sort — good for nearly-sorted/small input
Partition scheme (Lomuto vs Hoare, conceptually)
Counting sort — O(n + k), when values are bounded integers
Stability of a sort, and when it matters
`key=` parameter instead of writing custom comparators
Sorting by multiple criteria (`key=lambda x: (x[0], -x[1])`)
`functools.cmp_to_key` for legacy comparator-style sorting
10
Searching and Binary Search
1 sheet
Searching and Binary Search
Binary search on a sorted array — O(log n)
Writing binary search without off-by-one bugs (lo, hi, mid, loop invariant)
Binary search on the answer
Binary search on a rotated sorted array
Binary search for exact match vs "leftmost/rightmost occurrence"
Search in a 2D sorted matrix
`bisect.bisect_left` / `bisect.bisect_right`
bisect.insort for maintaining a sorted list
11
Stacks
1 sheet
Stacks
LIFO principle
Implementing a stack with list (append/pop from the end)
Valid parentheses / balanced brackets
Monotonic stack pattern (next greater/smaller element)
Evaluating expressions (postfix/infix, conceptually)
Using a stack to simulate recursion iteratively (e.g. DFS)
Min-stack (stack that tracks its own running minimum in O(1))
Why appending/popping from the end of a Python list is O(1) but from the front is O(n)
12
Queues and Deques
1 sheet
Queues and Deques
FIFO principle
Why list.pop(0) is O(n) — never use a plain list as a queue
collections.deque — O(1) append/pop from both ends
Queue via deque for BFS
Circular queue concept
Monotonic deque pattern (sliding window maximum)
Priority queue as a distinct structure from a plain queue
13
Linked Lists
1 sheet
Linked Lists
Singly linked list — node with value + next
Doubly linked list — node with prev + next
Why linked lists give O(1) insert/delete at a known position but O(n) access by index
Reversing a linked list (iterative and recursive)
Detecting a cycle (Floyd's fast/slow pointer)
Finding the middle of a list in one pass
Merging two sorted linked lists
Removing the Nth node from the end (two-pointer with a gap)
Dummy/sentinel head node trick (avoids edge-case branching)
14
Trees
1 sheet
Trees
Binary tree
Binary search tree (BST) and its ordering invariant
Balanced vs unbalanced trees (why balance matters for complexity)
BST insert, search, delete
Validating a BST
Lowest common ancestor (BST and general binary tree versions)
Computing height/depth
Diameter of a binary tree
Checking if a tree is balanced
01
How to Think About a Problem
1 sheet
How to Think About a Problem
Restate the problem in your own words
Identify input size and constraints
Work a small example by hand first
Identify the brute-force solution before optimizing
Name the pattern the problem resembles
Consider edge cases
Decide on a data structure before writing code
Trace through your own solution before trusting it
04
Strings
1 sheet
Strings
Palindrome checks
Anagram checks (via sorting or frequency count)
Basic pattern matching (naive substring search)
`ord()` / `chr()` for character-to-index tricks
Strings as immutable sequences (why in-place edits aren't free)
Building strings efficiently (join vs += in a loop)
Substring vs subsequence (distinction matters a lot)
Character frequency counting
`collections.Counter` for frequency maps
`str.find()` vs manual scanning
08
Recursion
1 sheet
Recursion
Base case and recursive case
The call stack, and how recursion depth relates to space complexity
Recursion on arrays/strings (divide the input, recurse on a piece)
Memoization as the bridge from recursion to dynamic programming
Tracing a recursion tree by hand
Head recursion vs tail recursion (Python doesn't optimize tail calls)
Converting recursion to iteration
Mutual recursion
`functools.lru_cache` for automatic memoization
11
Stacks
1 sheet
Stacks
LIFO principle
Implementing a stack with list (append/pop from the end)
Valid parentheses / balanced brackets
Monotonic stack pattern (next greater/smaller element)
Evaluating expressions (postfix/infix, conceptually)
Using a stack to simulate recursion iteratively (e.g. DFS)
Min-stack (stack that tracks its own running minimum in O(1))
Why appending/popping from the end of a Python list is O(1) but from the front is O(n)
14
Trees
1 sheet
Trees
Binary tree
Binary search tree (BST) and its ordering invariant
Balanced vs unbalanced trees (why balance matters for complexity)
BST insert, search, delete
Validating a BST
Lowest common ancestor (BST and general binary tree versions)
Computing height/depth
Diameter of a binary tree
Checking if a tree is balanced
02
Big-O and Complexity Analysis
1 sheet
Big-O and Complexity Analysis
Common complexity classes, in order
Analyzing loops (single, nested, sequential)
Membership check (`in`): list O(n) vs dict/set O(1) average
String concatenation in a loop is O(n²)
Dropping constants and lower-order terms
Time complexity vs space complexity
Reading constraints to guess required complexity
list index/append/pop-from-end: O(1)
list insert/pop/delete at an arbitrary index: O(n)
sorted() / list.sort(): O(n log n), Timsort
05
Hashing — Hash Maps and Sets
1 sheet
Hashing — Hash Maps and Sets
Using a hash map to trade space for time
Two Sum via hash map (canonical example)
Grouping (e.g. group anagrams) via hash map of lists
What a hash function does and why collisions happen
Using a set for "seen before" checks
Using a hash map as a frequency counter
Hashing tuples/frozensets for composite keys
`collections.defaultdict`
`collections.Counter` (`.most_common()`, arithmetic on counters)
Using tuples as dict keys (must be hashable — no lists inside)
09
Sorting Algorithms
1 sheet
Sorting Algorithms
Merge sort — O(n log n), stable, extra space
Quicksort — O(n log n) average, O(n²) worst case, in-place
`sorted()` and `list.sort()` — Timsort, stable, O(n log n)
Insertion sort — good for nearly-sorted/small input
Partition scheme (Lomuto vs Hoare, conceptually)
Counting sort — O(n + k), when values are bounded integers
Stability of a sort, and when it matters
`key=` parameter instead of writing custom comparators
Sorting by multiple criteria (`key=lambda x: (x[0], -x[1])`)
`functools.cmp_to_key` for legacy comparator-style sorting
12
Queues and Deques
1 sheet
Queues and Deques
FIFO principle
Why list.pop(0) is O(n) — never use a plain list as a queue
collections.deque — O(1) append/pop from both ends
Queue via deque for BFS
Circular queue concept
Monotonic deque pattern (sliding window maximum)
Priority queue as a distinct structure from a plain queue
03
Arrays and Lists
1 sheet
Arrays and Lists
Prefix sums
Kadane's algorithm (maximum subarray)
Cyclic sort pattern (numbers in range 1..n)
Dutch national flag / 3-way partition
Merging two sorted arrays in place
list.copy() vs assignment (aliasing pitfall)
Difference arrays (range-update trick)
Matrix traversal (row-major, column-major, diagonal, spiral)
Rotating an array (reversal trick)
Negative indexing and slicing (`a[::-1]`, `a[i:j]`)
06
Two Pointers
1 sheet
Two Pointers
Opposite-direction pointers (start/end converging)
Same-direction pointers (fast/slow at different rates)
Fast/slow pointers for cycle detection (Floyd's algorithm)
Merging two sorted structures with two pointers
Three pointers (e.g. 3Sum built on top of two pointers)
Recognizing when a problem on a sorted array/list is a two-pointer problem in disguise
07
Sliding Window
1 sheet
Sliding Window
Fixed-size window (e.g. max sum of size-k subarray)
Variable-size window that grows/shrinks based on a condition
Window state maintained incrementally (not recomputed each shift)
Longest substring without repeating characters
Minimum window substring
Longest substring with at most K distinct characters
Recognizing "contiguous subarray/substring satisfying X" as a sliding-window signal
10
Searching and Binary Search
1 sheet
Searching and Binary Search
Binary search on a sorted array — O(log n)
Writing binary search without off-by-one bugs (lo, hi, mid, loop invariant)
Binary search on the answer
Binary search on a rotated sorted array
Binary search for exact match vs "leftmost/rightmost occurrence"
Search in a 2D sorted matrix
`bisect.bisect_left` / `bisect.bisect_right`
bisect.insort for maintaining a sorted list
13
Linked Lists
1 sheet
Linked Lists
Singly linked list — node with value + next
Doubly linked list — node with prev + next
Why linked lists give O(1) insert/delete at a known position but O(n) access by index
Reversing a linked list (iterative and recursive)
Detecting a cycle (Floyd's fast/slow pointer)
Finding the middle of a list in one pass
Merging two sorted linked lists
Removing the Nth node from the end (two-pointer with a gap)
Dummy/sentinel head node trick (avoids edge-case branching)