Two Sum, sliding window, BFS on a grid — the problems that show up in every interview, with the data structure visible at every step. Pause, rewind, edit the input, and ask 'why does this work?' until you actually know.
New to this section? Work through these in order — each builds on the previous.
The brute-force solution checks every pair in O(n²). The hash-map trick: as we scan left-to-right, for each nums[i] we look up its complement (target − nums[i]) in a map of values we've already seen. The map turns the inner loop's linear scan into an O(1) lookup, so the whole thing runs in a single O(n) pass.
Walk left-to-right with a stack. Every opener gets pushed; every closer pops and must match the top. If you ever pop the wrong opener — or pop from an empty stack — the string is invalid. After the loop, the stack must be empty for the string to be valid. The stack is the perfect data structure here because brackets nest like function calls.
The brute force is to try every (buy, sell) pair — O(n²). The trick is realizing you don't need to revisit history: for each day, the best sell-today profit is today's price minus the cheapest price seen so far. So track running min and running max-profit in one pass.
To reach step n, the LAST move you made was either a 1-step (from n-1) or a 2-step (from n-2). So the number of ways to reach n is the sum of the ways to reach n-1 and n-2. That's Fibonacci. Building the dp table bottom-up — dp[0]=1, dp[1]=1, then dp[i] = dp[i-1] + dp[i-2] — gives O(n) time, O(n) space; you can compress to two variables for O(1) space.
Three pointers do the whole job: prev (everything we've reversed so far), curr (the node we're about to flip), and nxt (saved so we don't lose the rest of the list). On each iteration: save nxt, flip curr.next to point at prev, then march all three pointers one step forward. At the end, prev is the new head.
Two pointers, one for each list. Each step: compare heads, take the smaller one, advance that pointer. When one list runs out, append the rest of the other. The two lists must be pre-sorted; if they aren't, you're doing merge-sort's merge step on unsorted data and you'll get garbage.
At every index, you have one decision: extend the running subarray, or start fresh from here. You restart when the running sum has gone negative — a negative prefix can only hurt anything you'd add after it. This dynamic-programming insight collapses the O(n³) brute force into O(n), and it's exactly the same shape as 'best time to buy/sell stock' written with a different variable.
A variable-size sliding window. The right pointer always advances; the left pointer jumps forward whenever the incoming character would create a duplicate, shrinking the window until the offender is evicted. A hash set tracks what's in the window so the duplicate-check is O(1). Each character is visited at most twice (once by right, once by left) — total O(n).
Inorder = LEFT subtree, then NODE, then RIGHT subtree. The recursive version is three lines. The iterative version with an explicit stack is more interesting: you descend left as far as you can, pushing each node, then pop, visit, and try the right subtree. The stack lets you remember where to come back to. For BSTs, inorder produces values in sorted order — that's the property tests rely on.
Scan the grid row-by-row. Every time you hit unvisited land, you've found a new island — bump the count, then flood-fill the connected region so you don't double-count it. The flood-fill is just DFS (or BFS) over 4-directional neighbors, marking each cell as visited when you touch it. Each cell is processed at most once, so the total work is O(rows × cols).