NeetCode 150 — Full Roadmap in C++

“Do not solve NeetCode 150 in shuffle mode. Do it in pattern mode. The order teaches you.”

This is the definitive 12-week march through NeetCode 150 in C++. Every category gets: the pattern in three sentences, the canonical C++ template, three to five must-solve problems with links, a time budget, and a suggested order.

Official list, still maintained by Navi (Neetcode) as of 2026: https://neetcode.io/practice/practice/neetcode150 and https://neetcode.io/roadmap


How to use this file

  1. Do the categories in order. They build on each other. Arrays teaches loops, Two Pointers teaches invariants, Sliding Window teaches state maintenance, and so on. Do not skip ahead.

  2. First pass: solve in Python, port to C++. For every new pattern (i.e., the first two or three problems of a category), sketch in Python first, then translate. This separates inventing the solution from typing it.

  3. Second pass: C++ only, timed. Once you are three problems into a category, drop Python. Time yourself. Medium = 25 minutes. Easy = 12. Hard = 45.

  4. After each problem, write the pattern label + complexity in a one-line comment at the top of the file. This becomes your NeetCode-150 repo (Project P2.1).


Category 1 — Arrays & Hashing (9 problems, W9)

Pattern in 3 sentences. Traverse the array once, maintain a hash-map of “what have I seen and where.” Constant-time lookup on hash converts nested-loop O(n²) brute-force into linear O(n). This is the most common trick in the entire list; internalize it first.

Canonical template:

std::unordered_map<int, int> seen;
for (int i = 0; i < (int)nums.size(); ++i) {
    int need = target - nums[i];
    if (auto it = seen.find(need); it != seen.end()) {
        return {it->second, i};
    }
    seen[nums[i]] = i;
}

Must-solve (in order):

  1. 217. Contains Duplicate — warm-up

  2. 1. Two Sum — the archetype

  3. 242. Valid Anagram

  4. 49. Group Anagramsunordered_map<string, vector<string>>

  5. 347. Top K Frequent Elements — bucket sort or heap

  6. 238. Product of Array Except Self — the prefix/suffix trick

  7. 128. Longest Consecutive Sequence — careful about O(n)

Time budget: W9. ~6 hours total.


Category 2 — Two Pointers (5 problems, W10)

Pattern in 3 sentences. Two indices walk the array with an invariant maintained between them. Usually one starts left, one right, and they converge; sometimes both start left and one races ahead. Reduces two-loop O(n²) scans to O(n) when the array has monotonic structure (usually sorted).

Canonical template:

int l = 0, r = nums.size() - 1;
while (l < r) {
    int sum = nums[l] + nums[r];
    if (sum == target) return {l, r};
    if (sum < target) ++l;
    else --r;
}

Must-solve:

  1. 125. Valid Palindrome

  2. 167. Two Sum II — Sorted

  3. 15. 3Sum — the study classic; watch dedup logic

  4. 11. Container With Most Water

  5. 42. Trapping Rain Water — Hard; do it twice

Time budget: 4 hours.


Category 3 — Sliding Window (6 problems, W10)

Pattern in 3 sentences. Maintain a window [l, r) and a summary statistic (sum, count, hash-map). Grow r; when the invariant breaks, shrink l until it holds. Turns O(n·k) window-scans into amortized O(n).

Canonical template:

int l = 0, best = 0;
std::unordered_map<char, int> count;
for (int r = 0; r < (int)s.size(); ++r) {
    count[s[r]]++;
    while (/* invariant broken */) {
        count[s[l]]--;
        if (count[s[l]] == 0) count.erase(s[l]);
        ++l;
    }
    best = std::max(best, r - l + 1);
}

Must-solve:

  1. 121. Best Time to Buy and Sell Stock

  2. 3. Longest Substring Without Repeating

  3. 424. Longest Repeating Character Replacement

  4. 76. Minimum Window Substring — Hard; the sliding-window boss level

  5. 239. Sliding Window Maximum — introduces monotonic deque

Time budget: 6 hours.


Category 4 — Stack (7 problems, W11)

Pattern in 3 sentences. Use a LIFO structure to defer decisions until later context arrives. Monotonic stacks (kept sorted while pushing) solve “next greater / next smaller” families in O(n). Parenthesis/bracket problems and expression evaluators are all stack problems in disguise.

Canonical template (monotonic stack for next greater):

std::vector<int> ans(nums.size(), -1);
std::stack<int> st;  // indices, values strictly decreasing
for (int i = 0; i < (int)nums.size(); ++i) {
    while (!st.empty() && nums[st.top()] < nums[i]) {
        ans[st.top()] = nums[i];
        st.pop();
    }
    st.push(i);
}

Must-solve:

  1. 20. Valid Parentheses

  2. 155. Min Stack

  3. 150. Evaluate Reverse Polish Notation

  4. 22. Generate Parentheses — borderline backtracking

  5. 739. Daily Temperatures — canonical monotonic stack

  6. 84. Largest Rectangle in Histogram — Hard; do it twice

Time budget: 6 hours.


Category 5 — Binary Search (7 problems, W11)

Pattern in 3 sentences. Whenever the search space is monotonic in some predicate, halve it each step. The trick is recognizing the predicate: “is this a valid answer?” for binary-search-on-answer problems (BSoA). Learn to write the loop invariant (l < r, l r, half-open, etc.) and stick with one style.

Canonical template (half-open, no off-by-one):

int l = 0, r = n;  // search in [l, r)
while (l < r) {
    int m = l + (r - l) / 2;  // avoid overflow
    if (predicate(m)) r = m;
    else l = m + 1;
}
// l is the smallest index where predicate holds, or n if none

Must-solve:

  1. 704. Binary Search — the primitive

  2. 74. Search a 2D Matrix

  3. 875. Koko Eating Bananas — first BSoA

  4. 153. Find Min in Rotated Sorted Array

  5. 33. Search in Rotated Sorted Array — the classic

  6. 4. Median of Two Sorted Arrays — Hard; famously nasty

Time budget: 6 hours.


Category 6 — Linked List (11 problems, W12)

Pattern in 3 sentences. Two-pointer techniques (slow/fast for cycle and midpoint), reversal in place, and merge patterns cover 90% of linked-list problems. Draw the pointers on paper. Always — always — use a dummy head node to simplify edge cases at the start.

Canonical template (in-place reversal):

ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
    ListNode* next = curr->next;
    curr->next = prev;
    prev = curr;
    curr = next;
}
return prev;  // new head

Must-solve:

  1. 206. Reverse Linked List

  2. 21. Merge Two Sorted Lists

  3. 141. Linked List Cycle — Floyd’s tortoise-and-hare

  4. 143. Reorder List

  5. 19. Remove Nth From End

  6. 146. LRU Cache — Medium but sneaky; use list + unordered_map

  7. 23. Merge k Sorted Lists — heap-based; Hard

Time budget: 8 hours.


Category 7 — Trees (11 problems, W12–W13)

Pattern in 3 sentences. Trees are recursion made physical. Master DFS in three orders (pre/in/post) and BFS by level. BST problems reduce to “in-order gives sorted”; general-tree problems reduce to “post-order lets me combine child answers.”

Canonical template (post-order aggregation):

int solve(TreeNode* node) {
    if (!node) return 0;
    int l = solve(node->left);
    int r = solve(node->right);
    // combine l and r with node->val to produce this subtree's answer
    return /* ... */;
}

Must-solve:

  1. 226. Invert Binary Tree

  2. 104. Max Depth

  3. 543. Diameter — post-order aggregation

  4. 102. Level Order — BFS with queue

  5. 98. Validate BST — pass down min/max bounds

  6. 235/236. Lowest Common Ancestor

  7. 124. Binary Tree Max Path Sum — Hard; the archetype of “return one thing, track another globally”

  8. 297. Serialize and Deserialize — Hard

Time budget: 10 hours.


Category 8 — Tries (3 problems, W13)

Pattern in 3 sentences. A tree of prefix nodes, one child per possible character. Insertion/lookup/prefix-search all O(L) in the length of the key. See file 03 for the full implementation with delete support.

Must-solve:

  1. 208. Implement Trie

  2. 211. Design Add and Search Words — wildcard DFS on trie

  3. 212. Word Search II — Hard; trie + backtracking on grid

Time budget: 5 hours.


Category 9 — Heap / Priority Queue (7 problems, W13)

Pattern in 3 sentences. When you need the smallest (or largest) K, or a stream median, or repeatedly the current min/max of a changing set, reach for a heap. std::priority_queue is the tool; know the custom-comparator syntax cold (see file 01). For two-heap median tricks, keep one max-heap of the lower half and one min-heap of the upper half.

Must-solve:

  1. 703. Kth Largest in Stream

  2. 1046. Last Stone Weight

  3. 973. K Closest Points

  4. 215. Kth Largest Element — heap or quickselect

  5. 621. Task Scheduler

  6. 295. Find Median from Data Stream — Hard; the two-heap trick

Time budget: 6 hours.


Category 10 — Backtracking (9 problems, W14)

Pattern in 3 sentences. Depth-first exploration of a decision tree with explicit undo. The skeleton is always the same: try a choice, recurse, undo. The art is in pruning — spotting when a partial solution cannot possibly extend to a valid one.

Canonical template:

void backtrack(std::vector<int>& path, std::vector<std::vector<int>>& out, /*state*/) {
    if (/* base case */) {
        out.push_back(path);
        return;
    }
    for (auto choice : choices(/*state*/)) {
        if (!feasible(choice)) continue;
        path.push_back(choice);
        backtrack(path, out, /* updated state */);
        path.pop_back();  // the undo
    }
}

Must-solve:

  1. 78. Subsets

  2. 39. Combination Sum

  3. 46. Permutations

  4. 79. Word Search — grid backtracking

  5. 51. N-Queens — Hard

  6. 131. Palindrome Partitioning

Time budget: 8 hours.


Category 11 — Graphs (13 problems, W14–W15)

Pattern in 3 sentences. Every graph problem starts with a representation choice: adjacency list (vector<vector<int>>) is the default, adjacency matrix only for dense small graphs. BFS solves unweighted shortest path; DFS solves connectivity, cycle detection, and ordering. Grid problems are graph problems with implicit edges to the four (or eight) neighbors.

Canonical templates: See file 05 for BFS, DFS iterative and recursive, and grid neighbor patterns.

Must-solve:

  1. 200. Number of Islands — grid DFS/BFS

  2. 133. Clone Graph

  3. 417. Pacific Atlantic Water Flow — multi-source BFS

  4. 207. Course Schedule — cycle detection / topo

  5. 210. Course Schedule II — Kahn’s algorithm

  6. 994. Rotting Oranges — multi-source BFS

  7. 130. Surrounded Regions

  8. <phone_number_or_numberic_id_or_random_id_12>. Redundant Connection — first union-find problem

Time budget: 10 hours.


Category 12 — Advanced Graphs (6 problems, W15)

Pattern in 3 sentences. Weighted shortest paths (Dijkstra, Bellman-Ford, Floyd-Warshall) and MST (Kruskal, Prim). The overwhelming majority of study questions here are Dijkstra variants; know the priority_queue<pair<int,int>> form cold. See file 05 for the copy-paste template.

Must-solve:

  1. 743. Network Delay Time — straight Dijkstra

  2. 787. Cheapest Flights With K Stops — Bellman-Ford or Dijkstra with state

  3. 1584. Min Cost to Connect Points — MST

  4. <phone_number_or_numberic_id_or_random_id_13>. Swim in Rising Water — Dijkstra variant

  5. 269. Alien Dictionary — Hard; topological + string parse

Time budget: 8 hours.


Category 13 — 1D Dynamic Programming (12 problems, W16)

Pattern in 3 sentences. Identify the state (what does dp[i] mean?) and the transition (how does dp[i] derive from earlier dp[j]s?). Write the recursion first with memoization, then convert to bottom-up tabulation. Space-optimize last, and only if asked.

Canonical template (memo → tab):

// Memoized:
std::vector<int> memo(n, -1);
std::function<int(int)> f = [&](int i) -> int {
    if (i >= n) return 0;
    if (memo[i] != -1) return memo[i];
    return memo[i] = std::min(cost[i] + f(i+1), cost[i] + f(i+2));
};

// Tabulated:
std::vector<int> dp(n + 2, 0);
for (int i = n - 1; i >= 0; --i) {
    dp[i] = cost[i] + std::min(dp[i+1], dp[i+2]);
}

Must-solve:

  1. 70. Climbing Stairs — the primitive

  2. 746. Min Cost Climbing Stairs

  3. 198. House Robber

  4. 213. House Robber II — circular twist

  5. 5. Longest Palindromic Substring

  6. 139. Word Break

  7. 300. LIS — O(n²) DP then O(n log n) patience sorting

  8. 322. Coin Change — unbounded knapsack

Time budget: 10 hours.


Category 14 — 2D Dynamic Programming (11 problems, W17)

Pattern in 3 sentences. State is a pair (usually two indices into two strings, or (row, col) on a grid). Transitions come from the small neighborhood of (i, j). This is where DP goes from “comfortable” to “the study partner’s favorite filter.”

Must-solve:

  1. 62. Unique Paths — the primitive

  2. 1143. Longest Common Subsequence — the archetype

  3. 72. Edit Distance — the study classic

  4. 10. Regular Expression Matching — Hard

  5. 312. Burst Balloons — Hard, interval DP

  6. 518. Coin Change 2

Time budget: 10 hours.


Category 15 — Greedy (8 problems, W17)

Pattern in 3 sentences. Make the locally optimal choice at each step, and prove (or trust the problem-setter) that it composes into the global optimum. Greedy is deceptive: half the “greedy” LeetCode problems are actually DP problems that happen to admit a greedy solution. Always be able to argue why your greedy works.

Must-solve:

  1. 53. Max Subarray (Kadane) — the primitive

  2. 55. Jump Game

  3. 45. Jump Game II

  4. 134. Gas Station

  5. 846. Hand of Straights

Time budget: 6 hours.


Category 16 — Intervals (6 problems, W18)

Pattern in 3 sentences. Sort by start (occasionally by end), then sweep. Overlap check is a.end > b.start. Rooms/meeting problems reduce to “count concurrent events” via a sweep line or a min-heap of end times.

Canonical template (merge overlapping):

std::sort(intervals.begin(), intervals.end());
std::vector<std::vector<int>> out;
for (auto& iv : intervals) {
    if (!out.empty() && out.back()[1] >= iv[0]) {
        out.back()[1] = std::max(out.back()[1], iv[1]);
    } else {
        out.push_back(iv);
    }
}

Must-solve:

  1. 56. Merge Intervals

  2. 57. Insert Interval

  3. 435. Non-overlapping Intervals

  4. 252/253. Meeting Rooms II — min-heap of end times

Time budget: 5 hours.


Category 17 — Math & Geometry (8 problems, W18)

Pattern in 3 sentences. No unifying pattern; a grab-bag of matrix rotations, spiral traversals, modular arithmetic, and Pascal’s triangle. study-frequency is medium. Skip the rare ones, do the popular ones.

Must-solve:

  1. 48. Rotate Image — transpose + reverse

  2. 54. Spiral Matrix

  3. 73. Set Matrix Zeroes — the O(1) space trick

  4. 50. Pow(x, n) — fast exponentiation; watch integer overflow on n = INT_MIN

Time budget: 5 hours.


Category 18 — Bit Manipulation (7 problems, W18)

Pattern in 3 sentences. XOR pairs to zero (finds unique element in duplicates). n & (n-1) clears the lowest set bit. Learn to think of an integer as 32 flags.

Canonical tricks:

n & (n - 1);         // clears lowest set bit
n & (-n);            // isolates lowest set bit
__builtin_popcount(n);  // count set bits (GCC/Clang)
std::popcount(n);    // C++20 portable
std::countl_zero(n); // C++20, leading zeros

Must-solve:

  1. 136. Single Number — XOR trick

  2. 191. Number of 1 Bits

  3. 338. Counting Bits — DP + bit trick

  4. 268. Missing Number

  5. 190. Reverse Bits

Time budget: 4 hours.


Overall progress log template

Maintain this table in your NeetCode repo README as you go. Public accountability compounds.

Week

Category

# Solved

# In Budget

# Retries

Notes

W9

Arrays & Hashing

9 / 9

7 / 9

2

128 needed a second attempt


What most people get wrong

They do NeetCode in shuffle mode from LeetCode’s daily challenge feed. Then they wonder why their pattern recognition is weak six months later. The categorical order exists for a reason: your brain builds pattern-buckets, not problem-memories. Do the categories in order, do each pattern until you can state the pattern in one sentence and produce the template in ten seconds, then move on.

The second failure mode: they solve every problem once and never revisit. Retention decays. Set a weekly re-solve of 3 random previously-solved problems, timed. If you cannot re-solve in half the original time, the pattern has not stuck.


Nav: ← STL competitive · Custom data structures →