Hi👋SpeedAlgo • Deliberate Practice & Cognitive Ergonomics for Software Engineers

An interactive algorithm mastery and technical interview preparation platform published by Hi👋WebEnterprise. Built for senior and staff software engineers preparing for rigorous coding screens at top tech companies (FAANG/MAMAA).

13 Core Algorithmic Patterns & 225 Practice Problems

  • 1. Two Pointers (16 Paradigms, 43 Problems): Opposite ends, sorted pair sums, palindrome verification, trapping rain water, 3Sum, container with most water — includes the Sliding Window and Fast & Slow Pointers paradigms (contiguous subarray invariants, longest substrings, Floyd's cycle detection, linked list middle).
  • 2. Binary Search (9 Paradigms, 14 Problems): Monotonic predicate partitioning (feasible(x)), boundary search, rotated sorted arrays, square roots, minimum ship capacity, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (5 Paradigms, 11 Problems): Counting set bits, XOR cancellation, bit reversal, bitmask pairing, maximum XOR with a bitwise trie.
  • 4. Math & Geometry (8 Paradigms, 14 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (15 Paradigms, 24 Problems): Path sums, lowest common ancestor, tree diameter, validating BSTs, tree DP (House Robber III, Binary Tree Cameras).
  • 6. Tree/Graph Breadth-First Search (5 Paradigms, 12 Problems): Level-order traversals, shortest path in unweighted graphs, zig-zag traversals, rotting oranges, word ladders.
  • 7. Graphs (12 Paradigms, 22 Problems): Topological sort, cycle detection, Dijkstra's algorithm, bipartite graph validation, network delay.
  • 8. Backtracking (6 Paradigms, 14 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens, Sudoku solver.
  • 9. Dynamic Programming (13 Paradigms, 28 Problems): Memoization vs tabulation, 0/1 knapsack, unbounded knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (9 Paradigms, 11 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (7 Paradigms, 17 Problems): Trie (prefix tree), Union-Find (Disjoint Set Union), LRU Cache, LFU Cache, range-sum queries with updates.
  • 12. Stack (5 Paradigms, 9 Problems): Next greater element, largest rectangle in histogram, remove k digits, decode string, min stack.
  • 13. Intervals & Greedy (2 Paradigms, 6 Problems): Merge intervals, interval scheduling, meeting rooms by sweep line, jump game.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Read the pattern's mental model, loop invariant and Big-O proof, compare the pattern's template with the problem's solution side by side, and use the step-by-step debugger. The solution can also be shown in C#, Java, TypeScript, C++, Go or Rust for almost every problem.
  2. Stage 2 (Active Recall): Rebuild the solution from memory in a code editor, with an invariant checklist and optional progressive hints, and check it against a judged test suite.
  3. Stage 3 (AI Interview Coach, coming soon): A mock-interview stage still in development; for now, students go straight from Stage 2 to Stage 4.
  4. Stage 4 (Solve on Your Own): Solve a new problem on your own against a 15-minute timer; your code is graded against a test suite. Python and TypeScript run in your browser and C# runs on our server (design problems grade in Python and TypeScript).

Equipped with a spaced-repetition review hub on a fixed 7-step schedule (1 day up to 90 days), a two-pane Studio workspace, and study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Coins: New accounts get 40 free coins once, the daily claim adds +20 coins once a day, and inviting a friend earns you +25 coins when they complete their first practice step. These are the only ways to earn coins.
  • AI Coach: Each AI coach question costs 1-5 coins, priced by the server according to its size.
  • BYOK (Bring Your Own Key): AI coaching is free with your own Google Gemini, OpenAI or OpenRouter API key (BYOK).
  • Extras: Coins also unlock extras for 24 hours: a Recall hint level (1 coin), a Solve solution reveal (2), a LeetCode problem card's solutions (1) and a pattern's extra canonical problems (1).
  • Payments & Refunds: Nothing on the site is sold for money: coins can only be earned, never bought. There are no subscriptions or charges, so there is nothing to refund.
  • Platform Operator: Hi👋WebEnterprise. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

Arena
238Items
Theory Context•Advanced Data Structures
HardLC 305

Number of Islands II (LeetCode 305)

Target Frequency:GoogleAppleNetflix

Picture an m x n grid that begins entirely underwater (every cell 0). A stream of positions then arrives, each one a [row, col] cell that gets converted to land.

Every time one cell converts, tally the current total island count and stash it; return the whole list of those running tallies, one entry per conversion.

An island here means a maximal cluster of land cells touching horizontally or vertically; anything past the grid's outer edge counts as water.

Worked Examples

Example 1
Input:m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]]
Output:[1,1,2,3]
000000000
Explanation: The grid starts as all water. Adding land at (0,0) makes 1 island, and (0,1) joins it, still 1. (1,2) is not next to either, so there are 2 islands. (2,1) touches none of them, so there are 3.
Example 2
Input:m = 1, n = 1, positions = [[0,0]]
Output:[1]
0
Explanation: The only cell becomes land, forming 1 island.

⚖️Formal Constraints & Bounds

  • 1 <= m, n, positions.length <= 104

  • 1 <= m * n <= 104

  • positions[i].length == 2

  • 0 <= ri < m

  • 0 <= ci < n

Deep-Dive & Conceptual Insights

Core Insight

A cell always starts as its own island (+1); every successful union() with an already-land neighbor proves two previously-separate islands just fused, so it always costs exactly -1 -- the opposite signal of Redundant Connection's union() returning False for a cycle.

Real-World Scenario & Production Applications

Live incremental connectivity tracking in infrastructure-as-it-is-built systems: counting connected power grid segments, network partitions, or land-parcel clusters as new nodes come online one at a time, without re-scanning the whole system after each addition.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Online Cell Activation

For each incoming (r, c) in the stream, compute idx = r * n + c. If that cell is already land, the count is unchanged -- just re-report the current running total and move to the next operation.

Mathematical Recurrence / Code Invariant
idx = r * n + c
if is_land[idx]:
    result.append(island_count)
    continue

Step-by-Step Execution Trace Table

OperationCell (r,c)idxLand Neighbors FoundUnion MergesRunning island_count
1(0,0)0none01
2(0,1)1(0,0)1 (union(1,0))1
3(1,2)5none02
4(2,1)7none03
Code Shape
Archetype Code Shape
Python
1dsu = DSU(m * n)
2is_land = [False] * (m*n)
3island_count = 0
4result = []
5for r, c in positions:
6 idx = r*n + c
7 if is_land[idx]:
8 result.append(island_count)
9 continue
10 is_land[idx] = True
11 island_count += 1
12 for each of the 4 neighbors:
13 if the neighbor is land and dsu.union(idx, neighbor):
14 island_count -= 1
15 result.append(island_count)
16return result

Conceptual Narrative

The DSU Capstone: instead of re-flooding the entire grid after each land addition, an online Union-Find maintains running island counts incrementally in O(alpha(MN)) time per operation.

🧭 Conceptual Foundation & Pattern Intuition

Every other Number of Islands problem is offline: the full grid is provided up front, and one DFS/BFS pass counts connected components in O(M⋅N)O(M \cdot N)O(M⋅N) time. Number of Islands II is online: the grid starts entirely as water, and land cells arrive sequentially as a stream of KKK coordinates positions. After each individual addition, we must report the current total island count. Re-running flood-fill after each land addition would cost O(K⋅M⋅N)O(K \cdot M \cdot N)O(K⋅M⋅N), timing out instantly. The online fix uses Disjoint Set Union:

  1. Flatten 2D coordinates to a 1D index: idx = r * cols + c.
  2. When a land cell (r,c)(r, c)(r,c) arrives:
    • If it is already land (duplicate operation), the island count does not change.
    • Otherwise, mark it as land and increment island_count += 1 (it is initially its own new island).
  3. Inspect its 4 cardinal neighbors (North, South, East, West). If an adjacent neighbor is already land, attempt dsu.union(idx, neighbor_idx).
  4. If dsu.union() returns True (the neighbor belonged to a different island), those two islands have merged: decrement island_count -= 1.
🏝️ The Analogy: Raising Volcanic Atolls and Connecting Inter-Island Bridges

Imagine an empty ocean. An undersea volcano pushes an atoll above water. At that instant, it is a brand new solitary island (+1 island). The construction crew immediately inspects the 4 adjacent coordinates: if an neighboring plot of land already exists, they pour concrete to bridge them together. If that neighboring land was part of a separate island, the bridge fuses the two landmasses into one continuous island (-1 island). If the neighbor was already connected through a back-atoll horseshoe, the bridge is redundant and the island count remains unchanged.

🔑 Why It Works

The beauty is the exact semantic duality with cycle detection: in Redundant Connection, union == False signals a cycle; here, union == True signals that two previously isolated components fused, dictating an exact -1 adjustment.

  • Adding already existing land cell: If an incoming position is already land (grid[r][c] == 1), it is a duplicate operation and must NOT increment the island count.

  • Flattening 2D coordinates to 1D index: Correctly mapping (r, c) to r * n + c in the disjoint set parent array.

  • Unifying with non-land neighbor cells: Only perform union() with neighbor cells that are already initialized as land (grid[nr][nc] == 1).

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Grid starts all-water + a STREAM of add-land operations + must report the running island count after EACH operation.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: a newly-activated cell is its own island until proven otherwise; every union() that returns True (a real merge, not a self-loop) means two previously-distinct islands just became one, decrementing the count by exactly 1.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Re-running a full DFS/BFS flood-fill over the whole grid after each operation: this is the naive O(kmn) approach the online DSU exists to avoid.

  • Double-counting a merge: union() must only decrement the count when it returns True (roots were actually different), not on every neighbor check.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I maintain a DSU over all m*n grid cells plus a running island_count. For each incoming position, if it's already land I just re-report the current count. Otherwise I flip it to land, increment island_count by 1 (it starts as its own island), then check all 4 neighbors: for every neighbor that is already land, I call union() and decrement island_count by 1 for every successful (non-cycle) merge. I append island_count after every operation. This runs in O(k · alpha(mn)) amortized time instead of O(k · m · n) for k operations."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(k · alpha(mn))

Look at the execution steps: For each of k positions, one union-find find/union call per operation and a constant 4-neighbor scan. Each find/union is O(alpha(mn)) amortized with path compression and union by rank. Total: O(k · alpha(mn)).

SPACE COMPLEXITY

O(mn) Auxiliary

Look at memory allocations: parent, rank and is_land are each sized m*n, O(mn). find calls itself once per level of a tree, and union by rank keeps every tree at most log2(mn) + 1 levels tall, so the call stack is O(log(mn)). The result list holds one count per position.

Formal Recurrence Relation

T(k, m, n) = O(k · α(mn))

Derivation Progression

Per-Operation Activation

is_land[idx] = True; island_count += 1

O(1) constant-time activation and optimistic increment for each of the k operations.

4-Neighbor Union Scan

4 × union(idx, neighbor) = O(α(mn))

Checking and unioning with up to 4 cardinal neighbors, each union costing O(alpha(mn)) amortized.

Total Across k Operations

O(k · α(mn))

k operations, each O(alpha(mn)) amortized -- vastly cheaper than O(k · m · n) full re-scans.

Variable Definitions

kkk

Number of positions in the operation stream (positions.length)

m,nm, nm,n

Grid dimensions (rows, columns)

α(mn)α(mn)α(mn)

Inverse Ackermann function (α ≤ 4) from path compression + union by rank

Memory Architecture & Bounds

🟣 Call Stack

O(log(mn)) Recursive find, union by rank

🔵 Auxiliary Heap

O(mn) DSU parent + rank arrays and is_land boolean array

🟢 Output Space

O(k) Result list, one entry per operation

Boundary Best / Worst Cases

Best Case

O(k)O(k)O(k) if all positions are duplicates of already-land cells.

Average Case

O(k⋅α(mn))O(k \cdot \alpha(mn))O(k⋅α(mn))

Worst Case

O(k⋅α(mn))O(k \cdot \alpha(mn))O(k⋅α(mn)) full incremental merging.

Recurrence Tree Topology

Recurrence Tree Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "online incremental positions", "number of islands after each addLand operation". Dynamic connectivity in a 2D grid: land cells are added sequentially over time. Running DFS/BFS per query takes O(K×M⋅N)O(K \times M \cdot N)O(K×M⋅N) (104×104=10810^4 \times 10^4 = 10^8104×104=108 ops, TLE). A Senior SWE uses DSU with 2D-to-1D Index Flattening: each new land starts as an island (+1), and merging with adjacent existing land decrements count (-1).

CONSTRAINTS & BOUNDS

m,n≤104,k≤104m, n \le 10^4, k \le 10^4m,n≤104,k≤104 operations. Time budget: O(K⋅α(MN))O(K \cdot \alpha(MN))O(K⋅α(MN)) near-linear time (<50< 50<50ms).

FAANG PRODUCTION TRAPS & EDGE CASES

Duplicate operations: if the same position (r,c)(r, c)(r,c) is added multiple times, do NOT increment count; append the current count directly.

Theory Context•Advanced Data Structures
HardLC 305

Number of Islands II (LeetCode 305)

Target Frequency:GoogleAppleNetflix

Picture an m x n grid that begins entirely underwater (every cell 0). A stream of positions then arrives, each one a [row, col] cell that gets converted to land.

Every time one cell converts, tally the current total island count and stash it; return the whole list of those running tallies, one entry per conversion.

An island here means a maximal cluster of land cells touching horizontally or vertically; anything past the grid's outer edge counts as water.

Worked Examples

Example 1
Input:m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]]
Output:[1,1,2,3]
000000000
Explanation: The grid starts as all water. Adding land at (0,0) makes 1 island, and (0,1) joins it, still 1. (1,2) is not next to either, so there are 2 islands. (2,1) touches none of them, so there are 3.
Example 2
Input:m = 1, n = 1, positions = [[0,0]]
Output:[1]
0
Explanation: The only cell becomes land, forming 1 island.

⚖️Formal Constraints & Bounds

  • 1 <= m, n, positions.length <= 104

  • 1 <= m * n <= 104

  • positions[i].length == 2

  • 0 <= ri < m

  • 0 <= ci < n

Deep-Dive & Conceptual Insights

Core Insight

A cell always starts as its own island (+1); every successful union() with an already-land neighbor proves two previously-separate islands just fused, so it always costs exactly -1 -- the opposite signal of Redundant Connection's union() returning False for a cycle.

Real-World Scenario & Production Applications

Live incremental connectivity tracking in infrastructure-as-it-is-built systems: counting connected power grid segments, network partitions, or land-parcel clusters as new nodes come online one at a time, without re-scanning the whole system after each addition.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Online Cell Activation

For each incoming (r, c) in the stream, compute idx = r * n + c. If that cell is already land, the count is unchanged -- just re-report the current running total and move to the next operation.

Mathematical Recurrence / Code Invariant
idx = r * n + c
if is_land[idx]:
    result.append(island_count)
    continue

Step-by-Step Execution Trace Table

OperationCell (r,c)idxLand Neighbors FoundUnion MergesRunning island_count
1(0,0)0none01
2(0,1)1(0,0)1 (union(1,0))1
3(1,2)5none02
4(2,1)7none03
Code Shape
Archetype Code Shape
Python
1dsu = DSU(m * n)
2is_land = [False] * (m*n)
3island_count = 0
4result = []
5for r, c in positions:
6 idx = r*n + c
7 if is_land[idx]:
8 result.append(island_count)
9 continue
10 is_land[idx] = True
11 island_count += 1
12 for each of the 4 neighbors:
13 if the neighbor is land and dsu.union(idx, neighbor):
14 island_count -= 1
15 result.append(island_count)
16return result

Conceptual Narrative

The DSU Capstone: instead of re-flooding the entire grid after each land addition, an online Union-Find maintains running island counts incrementally in O(alpha(MN)) time per operation.

🧭 Conceptual Foundation & Pattern Intuition

Every other Number of Islands problem is offline: the full grid is provided up front, and one DFS/BFS pass counts connected components in O(M⋅N)O(M \cdot N)O(M⋅N) time. Number of Islands II is online: the grid starts entirely as water, and land cells arrive sequentially as a stream of KKK coordinates positions. After each individual addition, we must report the current total island count. Re-running flood-fill after each land addition would cost O(K⋅M⋅N)O(K \cdot M \cdot N)O(K⋅M⋅N), timing out instantly. The online fix uses Disjoint Set Union:

  1. Flatten 2D coordinates to a 1D index: idx = r * cols + c.
  2. When a land cell (r,c)(r, c)(r,c) arrives:
    • If it is already land (duplicate operation), the island count does not change.
    • Otherwise, mark it as land and increment island_count += 1 (it is initially its own new island).
  3. Inspect its 4 cardinal neighbors (North, South, East, West). If an adjacent neighbor is already land, attempt dsu.union(idx, neighbor_idx).
  4. If dsu.union() returns True (the neighbor belonged to a different island), those two islands have merged: decrement island_count -= 1.
🏝️ The Analogy: Raising Volcanic Atolls and Connecting Inter-Island Bridges

Imagine an empty ocean. An undersea volcano pushes an atoll above water. At that instant, it is a brand new solitary island (+1 island). The construction crew immediately inspects the 4 adjacent coordinates: if an neighboring plot of land already exists, they pour concrete to bridge them together. If that neighboring land was part of a separate island, the bridge fuses the two landmasses into one continuous island (-1 island). If the neighbor was already connected through a back-atoll horseshoe, the bridge is redundant and the island count remains unchanged.

🔑 Why It Works

The beauty is the exact semantic duality with cycle detection: in Redundant Connection, union == False signals a cycle; here, union == True signals that two previously isolated components fused, dictating an exact -1 adjustment.

  • Adding already existing land cell: If an incoming position is already land (grid[r][c] == 1), it is a duplicate operation and must NOT increment the island count.

  • Flattening 2D coordinates to 1D index: Correctly mapping (r, c) to r * n + c in the disjoint set parent array.

  • Unifying with non-land neighbor cells: Only perform union() with neighbor cells that are already initialized as land (grid[nr][nc] == 1).

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Grid starts all-water + a STREAM of add-land operations + must report the running island count after EACH operation.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: a newly-activated cell is its own island until proven otherwise; every union() that returns True (a real merge, not a self-loop) means two previously-distinct islands just became one, decrementing the count by exactly 1.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Re-running a full DFS/BFS flood-fill over the whole grid after each operation: this is the naive O(kmn) approach the online DSU exists to avoid.

  • Double-counting a merge: union() must only decrement the count when it returns True (roots were actually different), not on every neighbor check.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I maintain a DSU over all m*n grid cells plus a running island_count. For each incoming position, if it's already land I just re-report the current count. Otherwise I flip it to land, increment island_count by 1 (it starts as its own island), then check all 4 neighbors: for every neighbor that is already land, I call union() and decrement island_count by 1 for every successful (non-cycle) merge. I append island_count after every operation. This runs in O(k · alpha(mn)) amortized time instead of O(k · m · n) for k operations."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(k · alpha(mn))

Look at the execution steps: For each of k positions, one union-find find/union call per operation and a constant 4-neighbor scan. Each find/union is O(alpha(mn)) amortized with path compression and union by rank. Total: O(k · alpha(mn)).

SPACE COMPLEXITY

O(mn) Auxiliary

Look at memory allocations: parent, rank and is_land are each sized m*n, O(mn). find calls itself once per level of a tree, and union by rank keeps every tree at most log2(mn) + 1 levels tall, so the call stack is O(log(mn)). The result list holds one count per position.

Formal Recurrence Relation

T(k, m, n) = O(k · α(mn))

Derivation Progression

Per-Operation Activation

is_land[idx] = True; island_count += 1

O(1) constant-time activation and optimistic increment for each of the k operations.

4-Neighbor Union Scan

4 × union(idx, neighbor) = O(α(mn))

Checking and unioning with up to 4 cardinal neighbors, each union costing O(alpha(mn)) amortized.

Total Across k Operations

O(k · α(mn))

k operations, each O(alpha(mn)) amortized -- vastly cheaper than O(k · m · n) full re-scans.

Variable Definitions

kkk

Number of positions in the operation stream (positions.length)

m,nm, nm,n

Grid dimensions (rows, columns)

α(mn)α(mn)α(mn)

Inverse Ackermann function (α ≤ 4) from path compression + union by rank

Memory Architecture & Bounds

🟣 Call Stack

O(log(mn)) Recursive find, union by rank

🔵 Auxiliary Heap

O(mn) DSU parent + rank arrays and is_land boolean array

🟢 Output Space

O(k) Result list, one entry per operation

Boundary Best / Worst Cases

Best Case

O(k)O(k)O(k) if all positions are duplicates of already-land cells.

Average Case

O(k⋅α(mn))O(k \cdot \alpha(mn))O(k⋅α(mn))

Worst Case

O(k⋅α(mn))O(k \cdot \alpha(mn))O(k⋅α(mn)) full incremental merging.

Recurrence Tree Topology

Recurrence Tree Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "online incremental positions", "number of islands after each addLand operation". Dynamic connectivity in a 2D grid: land cells are added sequentially over time. Running DFS/BFS per query takes O(K×M⋅N)O(K \times M \cdot N)O(K×M⋅N) (104×104=10810^4 \times 10^4 = 10^8104×104=108 ops, TLE). A Senior SWE uses DSU with 2D-to-1D Index Flattening: each new land starts as an island (+1), and merging with adjacent existing land decrements count (-1).

CONSTRAINTS & BOUNDS

m,n≤104,k≤104m, n \le 10^4, k \le 10^4m,n≤104,k≤104 operations. Time budget: O(K⋅α(MN))O(K \cdot \alpha(MN))O(K⋅α(MN)) near-linear time (<50< 50<50ms).

FAANG PRODUCTION TRAPS & EDGE CASES

Duplicate operations: if the same position (r,c)(r, c)(r,c) is added multiple times, do NOT increment count; append the current count directly.

© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•