Data Structures & Algorithms
Crack the coding interview: build every data structure from scratch, master the patterns, from arrays and hashing to graphs and dynamic programming.
11 projects, 275 hands-on levels, run in your browser.
Syllabus
- Foundations: code through algorithms: Never written code before? Start here. You will learn the basics of Python, output, variables, types, decisions, loops, and functions, through the building blocks of algorithms: values, indexes, searches, and totals. By the end you are ready for Project 1.
- Complexity, Arrays & Hashing: Practice estimating work with Big-O, scanning arrays, building prefix sums and updating lists in place. Use sets and dictionaries to track duplicates, frequencies and earlier values. Compare the time and memory used by each approach.
- Two Pointers & Sliding Window: Use two indices to compare, merge and rearrange sequences. Maintain sums, counts and other state as a window moves through an array or string. Learn which input assumptions let each pointer move safely.
- Stacks, Queues & Strings: Build stacks and queues, then use them to match brackets, evaluate expressions and process values in order. Practice string operations and use monotonic stacks or deques to keep useful candidates for later queries.
- Binary Search & Sorting: Use sorted order to narrow a search, then apply feasibility checks to search for a minimum speed or capacity. Implement sorting algorithms and use ordered intervals to solve merging and scheduling problems.
- Linked Lists: Build and traverse linked lists, then practice reversing, merging, finding cycles, and preserving node identity. Implement a doubly linked list and an OrderedDict-based LRU cache. Finish with stable list sorting and pairwise merging of multiple sorted lists.
- Trees & Binary Search Trees: Build binary trees and practice traversal, depth, balance, diameter, paths and ancestor queries. Binary search tree ordering supports O(height) search, which is O(log n) when the tree is balanced and O(n) when skewed.
- Heaps, Priority Queues & Tries: Use heaps to select priorities, track ranks and medians, and merge sorted inputs. A binary heap exposes its minimum in constant time and removes it in logarithmic time. Build tries to distinguish complete words from prefixes and support wildcard searches.
- Graphs & Advanced Graphs: Represent relationships with adjacency lists, then explore them with breadth-first and depth-first search. Apply traversal to grids, order prerequisites, track connected components and find shortest paths under the appropriate weight assumptions.
- Recursion, Backtracking & Greedy: Trace recursive calls and base cases, then generate subsets, permutations and combinations. Use backtracking to explore choices and greedy rules when a local decision can be justified. Compare the assumptions that make each method correct.
- Dynamic Programming + Capstone: Learn to define a subproblem, choose its base cases, and reuse earlier answers. Start with stairs and house choices, then work through coins, sequences, grids, and strings. Compare rolling states, tables, and center expansion before combining these ideas in selection, counting, and stock-cooldown problems.
Key concepts
- Adjacency list: A graph representation where each node stores the neighbors reachable from it. It is space-efficient for sparse graphs and is the usual input shape for DFS, BF…
- Array: A contiguous, indexable sequence of values. In Python the closest everyday structure is a list ; DSA problems use arrays for scans, prefix sums, two-pointer te…
- Backtracking: A recursive search pattern that builds a candidate, explores it, then undoes the choice. It is used for permutations, combinations, subsets, constraint puzzles…
- Binary search: Repeatedly halves a sorted search space by asking whether the answer is left or right of the midpoint. Beyond arrays, it can search over an answer range when a…
- Binary search tree: A binary tree where left descendants are smaller and right descendants are larger than the node. This ordering supports search and validates many recursive bou…
- Breadth-first search: A traversal that explores all nodes at the current distance before moving farther. BFS is the standard shortest-path method for unweighted graphs and level-ord…
- Depth-first search: A traversal that explores one branch as far as possible before backtracking. DFS appears in trees, graphs, connected components, cycle detection, topological r…
- Dijkstra's algorithm: A shortest-path algorithm for graphs with nonnegative edge weights. It repeatedly expands the currently cheapest known node using a priority queue until all sh…
- Dynamic programming: A method for problems with overlapping subproblems and optimal substructure. Instead of recomputing the same state repeatedly, DP stores answers and combines t…
- Fast/slow pointers: A linked-list technique where one pointer advances faster than another. It detects cycles, finds middle nodes, locates cycle starts, and avoids storing every v…
- Graph: A set of nodes connected by edges. Graph problems model networks, dependencies, grids, relationships, and routes, then use traversal or shortest-path algorithm…
- Greedy algorithm: An algorithm that makes the locally best choice at each step and never revisits it. Greedy works only when local choices can be proven to lead to a global opti…
- Hash map: A key-value table that usually gives O(1) average lookup, insert, and delete. It is the main tool for counting frequencies, remembering seen values, and turnin…
- Heap: A tree-shaped priority structure where the smallest or largest item can be removed quickly. In Python, heapq is a min-heap used for top-k, merging sorted strea…
- Linked list: A sequence made of nodes where each node points to the next node. Linked-list problems test pointer rewiring, sentinel nodes, cycle detection, reversal, mergin…
- Memoization: Top-down dynamic programming: write the natural recursive solution, cache each state's answer, and reuse it when the state appears again. It is often the f…
- Monotonic stack: A stack kept in increasing or decreasing order by popping weaker candidates before pushing a new value. It solves nearest greater/smaller element, stock span,…
- Prefix sum: A running total where prefix[i] stores the sum before or through index i . It turns range-sum queries into subtraction and often pairs with a hash map to count…
- Priority queue: A queue where the next item is chosen by priority rather than arrival time. It is commonly implemented with a heap and used when the next cheapest, earliest, o…
- Queue: A first-in, first-out structure: the oldest item is removed first. It is the natural structure for BFS, level-order tree traversal, and processing work in arri…
- Set: A collection of unique values optimized for membership checks. Use a set when you only care whether something has appeared, not how many times or where it appe…
- Sliding window: A two-pointer pattern that keeps a moving subarray or substring while updating its state incrementally. It is ideal for longest, shortest, or counted ranges un…
- Sorting: Putting values into a defined order so later logic becomes simpler. Sorting often costs O(n log n), but it unlocks binary search, two pointers, interval mergin…
- Stack: A last-in, first-out structure: the newest item is removed first. It models nested structure, undo behavior, DFS, and problems where you need to remember unres…
- Tabulation: Bottom-up dynamic programming: fill a table in an order where every needed smaller state is already known. It usually avoids recursion depth issues and makes s…
- Tree: A connected structure with parent-child relationships and no cycles. Tree problems usually rely on recursion, DFS, BFS, or combining answers from subtrees.
- Trie: A prefix tree for strings where each edge represents a character. Tries make prefix lookup, autocomplete, word search, and dictionary matching efficient when m…
- Two pointers: A technique that moves two indices through a sequence, often from opposite ends or at different speeds. It works when the problem has order, sorted input, or a…