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•Priority Queue / Heap
HardLC 295

Find Median from Data Stream (LeetCode 295)

Target Frequency:AmazonMetaNetflix

The median of a sorted list of numbers is its middle value; when the list has an even number of entries, the median is instead the average of the two values nearest the center.

  • For example, the median of [2,3,4] is 3.
  • For example, the median of [2,3] is (2 + 3) / 2 = 2.5.

Design a MedianFinder class that supports:

  • MedianFinder() — creates an empty MedianFinder.
  • void addNum(int num) — feeds the next integer num from an incoming stream into the structure.
  • double findMedian() — returns the median of every number seen so far, accurate to within 10^-5.

Worked Examples

Example 1
Input:["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [[], [1], [2], [], [3], []]
Output:[null, null, null, 1.5, null, 2.0]
Explanation: After adding 1 and 2, the median is (1 + 2) / 2 = 1.5. After adding 3, the numbers are [1, 2, 3] and the median is 2.0.

⚖️Formal Constraints & Bounds

  • -105 <= num <= 105

  • There will be at least one element in the data structure before calling findMedian.

  • At most 5 * 104 calls will be made to addNum and findMedian.

Deep-Dive & Conceptual Insights

Core Insight

Splitting data across two heaps keeps the median continuously pinned at the tops of the two heaps.

Real-World Scenario & Production Applications

Financial high-frequency trading real-time bid-ask spread tracking and network QoS packet latency SLA monitoring.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Two-Heap Partition Invariant

Maintain small (max-heap of lower half numbers) and large (min-heap of upper half numbers). Invariant: every element in small is <= every element in large.

Mathematical Recurrence / Code Invariant
# Invariant: max(small) <= min(large)
# Size invariant: len(small) == len(large) (+ 1)

Step-by-Step Execution Trace Table

StepStream Value Addedsmall (Max-Heap)large (Min-Heap)Calculated Median
15[5][]5.0 (odd count →\to→ top of small)
215[5][15](5 + 15) / 2 = 10.0
31[5, 1][15]5.0 (rebalanced)
43[3, 1][5, 15](3 + 5) / 2 = 4.0
Code Shape
Archetype Code Shape
Python
1small = max_heap (lower half)
2large = min_heap (upper half)
3def addNum(num):
4 push num to small
5 if top(small) > top(large):
6 move top(small) to large
7 move one top across so that small holds len(large) or len(large) + 1 values
8def findMedian():
9 if len(small) > len(large):
10 return top(small)
11 return the average of top(small) and top(large)

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition
Code / Blueprint
The median splits an ordered collection into two equal halves. To maintain this dynamically without full sorting on every insertion, we divide the data between two heaps: a max-heap (`small`) storing the lower half and a min-heap (`large`) storing the upper half. Maintaining the order invariant $\max(small) \le \min(large)$ and the balance invariant $|small| - |large| \in {0, 1}$ allows retrieving the median in $O(1)$ time while inserting in $O(\log N)$.
 
⚖️ The Analogy: A Seesaw With the Small Half on One Side, the Big Half on the Other

Picture every number seen so far sorted into two piles: a "small half" pile (holding the smaller-valued numbers) and a "large half" pile (holding the larger-valued ones). Keep the two piles balanced in size, differing by at most one. If they're balanced, the median is the average of the tallest card in the small pile and the shortest card in the large pile — both instantly visible on top of their respective piles. If one pile has exactly one extra card, that top card alone is the median.

🔑 The Key Idea in the Code

small is a max-heap (values negated, since Python's heapq is min-heap-only) so its top is always the largest of the small half; large is a plain min-heap so its top is always the smallest of the large half — together, those two values are always the two numbers straddling the true middle of the whole dataset.

  • Direct comparison without heap balancing: Pushing directly to a heap without rebalancing sizes. The two heaps small (max-heap) and large (min-heap) must never differ in size by more than 1.

  • Crossing heap boundaries (max of small > min of large): Pushing directly into small or large can violate the invariant small[0] <= large[0]. Always route incoming numbers through one heap to the other to preserve ordering.

  • Float division on even size: When total count is even, median is (-small[0] + large[0]) / 2.0. In Python 2 or typed languages, integer division (a + b) / 2 truncates decimals.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Streaming data + continuous median retrieval.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule in addNum: push to small; if -small[0] > large[0], move that top to large; then rebalance so len(small) is len(large) or one more. findMedian reads -small[0] (odd count) or averages it with large[0] (even count).

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • addNum: fix the order (-small[0] > large[0]) before the sizes. A size fix first can be undone by the order move, leaving large one longer than small.

  • Integer division when computing average of two roots for even stream size.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use Two Heaps: a max-heap small for the lower half and a min-heap large for the upper half, so the middle values are always the two tops. In addNum I push the number to small. Then I fix the order: if small's top is bigger than large's top, I move it across. Only after that do I fix the sizes, moving one top across so small has the same count as large or one more. The trap is doing those two fixes the other way round: a size fix first can be undone by the order move, leaving large one longer. findMedian reads small's top when the count is odd and averages both tops when it is even. addNum is O(log N), findMedian is O(1), and the two heaps hold all N numbers, O(N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(log N) Add, O(1) Find

Look at the execution steps: Two balanced heaps: max-heap small (lower half) and min-heap large (upper half). Adding number costs O(log N) heap sift. Finding median reads heap roots in O(1) time.

SPACE COMPLEXITY

O(N) Auxiliary

Look at memory allocations: Call stack uses O(1). Two heaps storing all N streamed elements total O(N) space.

Formal Recurrence Relation

Tadd = O(log N), Tfind = O(1)

Derivation Progression

Heap Sift Insertion

O(log N) heap push

Pushes incoming value into appropriate half.

Size Invariant Balancing

0 ≤ |small| - |large| ≤ 1

Rebalances heap sizes in O(log N) root transfer.

Instant Median Calculation

O(1) peek small[0] or (small[0] + large[0]) / 2

Extracts median in strict constant time.

Variable Definitions

NNN

Total number of numbers added to the stream so far

Memory Architecture & Bounds

🟣 Call Stack

O(1)

🔵 Auxiliary Heap

O(N) Two heaps storing N elements

🟢 Output Space

O(1) Float median value

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1) findMedian, O(log⁡N)O(\log N)O(logN) addNum.

Average Case

O(log⁡N)O(\log N)O(logN).

Worst Case

O(log⁡N)O(\log N)O(logN) addNum.

Binary Heap Priority Queue Tree

Binary Heap Priority Queue Tree
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "find median from data stream", "addNum in O(log N)", "findMedian in O(1)". The median is the value splitting an ordered dataset into two equal halves. Maintaining a sorted array requires O(N)O(N)O(N) insertion. A Senior SWE immediately applies Two Balanced Heaps: a max-heap small storing the lower half, and a min-heap large storing the upper half.

CONSTRAINTS & BOUNDS

Up to 5×1045 \times 10^45×104 calls to addNum and findMedian. Time budget: strictly O(log⁡N)O(\log N)O(logN) per insertion and O(1)O(1)O(1) per median lookup. Auxiliary space: O(N)O(N)O(N) across the two heaps.

FAANG PRODUCTION TRAPS & EDGE CASES

small stores negated values, so read its top as -small[0]. The even-count median must be a float average of the two tops.

Core Algorithmic State Invariants

  1. Follow-Up: Every Value in [0, 100]

LeetCode's first follow-up bounds the values to [0, 100]. Then the heaps are not needed: keep a count per value (101 buckets) and a total. addNum is one increment, and findMedian walks at most 101 buckets to the middle position(s), so memory no longer grows with the stream.

  1. Follow-Up: 99% of Values in [0, 100]

The second follow-up lets 1% of values fall outside [0, 100]. With fewer than half the values on either side of the range, the median always lies inside it, so the 101 buckets still find it; values below 0 or above 100 only need to be counted, to know how far into the buckets the middle position is.

Theory Context•Priority Queue / Heap
HardLC 295

Find Median from Data Stream (LeetCode 295)

Target Frequency:AmazonMetaNetflix

The median of a sorted list of numbers is its middle value; when the list has an even number of entries, the median is instead the average of the two values nearest the center.

  • For example, the median of [2,3,4] is 3.
  • For example, the median of [2,3] is (2 + 3) / 2 = 2.5.

Design a MedianFinder class that supports:

  • MedianFinder() — creates an empty MedianFinder.
  • void addNum(int num) — feeds the next integer num from an incoming stream into the structure.
  • double findMedian() — returns the median of every number seen so far, accurate to within 10^-5.

Worked Examples

Example 1
Input:["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [[], [1], [2], [], [3], []]
Output:[null, null, null, 1.5, null, 2.0]
Explanation: After adding 1 and 2, the median is (1 + 2) / 2 = 1.5. After adding 3, the numbers are [1, 2, 3] and the median is 2.0.

⚖️Formal Constraints & Bounds

  • -105 <= num <= 105

  • There will be at least one element in the data structure before calling findMedian.

  • At most 5 * 104 calls will be made to addNum and findMedian.

Deep-Dive & Conceptual Insights

Core Insight

Splitting data across two heaps keeps the median continuously pinned at the tops of the two heaps.

Real-World Scenario & Production Applications

Financial high-frequency trading real-time bid-ask spread tracking and network QoS packet latency SLA monitoring.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Two-Heap Partition Invariant

Maintain small (max-heap of lower half numbers) and large (min-heap of upper half numbers). Invariant: every element in small is <= every element in large.

Mathematical Recurrence / Code Invariant
# Invariant: max(small) <= min(large)
# Size invariant: len(small) == len(large) (+ 1)

Step-by-Step Execution Trace Table

StepStream Value Addedsmall (Max-Heap)large (Min-Heap)Calculated Median
15[5][]5.0 (odd count →\to→ top of small)
215[5][15](5 + 15) / 2 = 10.0
31[5, 1][15]5.0 (rebalanced)
43[3, 1][5, 15](3 + 5) / 2 = 4.0
Code Shape
Archetype Code Shape
Python
1small = max_heap (lower half)
2large = min_heap (upper half)
3def addNum(num):
4 push num to small
5 if top(small) > top(large):
6 move top(small) to large
7 move one top across so that small holds len(large) or len(large) + 1 values
8def findMedian():
9 if len(small) > len(large):
10 return top(small)
11 return the average of top(small) and top(large)

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition
Code / Blueprint
The median splits an ordered collection into two equal halves. To maintain this dynamically without full sorting on every insertion, we divide the data between two heaps: a max-heap (`small`) storing the lower half and a min-heap (`large`) storing the upper half. Maintaining the order invariant $\max(small) \le \min(large)$ and the balance invariant $|small| - |large| \in {0, 1}$ allows retrieving the median in $O(1)$ time while inserting in $O(\log N)$.
 
⚖️ The Analogy: A Seesaw With the Small Half on One Side, the Big Half on the Other

Picture every number seen so far sorted into two piles: a "small half" pile (holding the smaller-valued numbers) and a "large half" pile (holding the larger-valued ones). Keep the two piles balanced in size, differing by at most one. If they're balanced, the median is the average of the tallest card in the small pile and the shortest card in the large pile — both instantly visible on top of their respective piles. If one pile has exactly one extra card, that top card alone is the median.

🔑 The Key Idea in the Code

small is a max-heap (values negated, since Python's heapq is min-heap-only) so its top is always the largest of the small half; large is a plain min-heap so its top is always the smallest of the large half — together, those two values are always the two numbers straddling the true middle of the whole dataset.

  • Direct comparison without heap balancing: Pushing directly to a heap without rebalancing sizes. The two heaps small (max-heap) and large (min-heap) must never differ in size by more than 1.

  • Crossing heap boundaries (max of small > min of large): Pushing directly into small or large can violate the invariant small[0] <= large[0]. Always route incoming numbers through one heap to the other to preserve ordering.

  • Float division on even size: When total count is even, median is (-small[0] + large[0]) / 2.0. In Python 2 or typed languages, integer division (a + b) / 2 truncates decimals.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Streaming data + continuous median retrieval.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule in addNum: push to small; if -small[0] > large[0], move that top to large; then rebalance so len(small) is len(large) or one more. findMedian reads -small[0] (odd count) or averages it with large[0] (even count).

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • addNum: fix the order (-small[0] > large[0]) before the sizes. A size fix first can be undone by the order move, leaving large one longer than small.

  • Integer division when computing average of two roots for even stream size.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use Two Heaps: a max-heap small for the lower half and a min-heap large for the upper half, so the middle values are always the two tops. In addNum I push the number to small. Then I fix the order: if small's top is bigger than large's top, I move it across. Only after that do I fix the sizes, moving one top across so small has the same count as large or one more. The trap is doing those two fixes the other way round: a size fix first can be undone by the order move, leaving large one longer. findMedian reads small's top when the count is odd and averages both tops when it is even. addNum is O(log N), findMedian is O(1), and the two heaps hold all N numbers, O(N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(log N) Add, O(1) Find

Look at the execution steps: Two balanced heaps: max-heap small (lower half) and min-heap large (upper half). Adding number costs O(log N) heap sift. Finding median reads heap roots in O(1) time.

SPACE COMPLEXITY

O(N) Auxiliary

Look at memory allocations: Call stack uses O(1). Two heaps storing all N streamed elements total O(N) space.

Formal Recurrence Relation

Tadd = O(log N), Tfind = O(1)

Derivation Progression

Heap Sift Insertion

O(log N) heap push

Pushes incoming value into appropriate half.

Size Invariant Balancing

0 ≤ |small| - |large| ≤ 1

Rebalances heap sizes in O(log N) root transfer.

Instant Median Calculation

O(1) peek small[0] or (small[0] + large[0]) / 2

Extracts median in strict constant time.

Variable Definitions

NNN

Total number of numbers added to the stream so far

Memory Architecture & Bounds

🟣 Call Stack

O(1)

🔵 Auxiliary Heap

O(N) Two heaps storing N elements

🟢 Output Space

O(1) Float median value

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1) findMedian, O(log⁡N)O(\log N)O(logN) addNum.

Average Case

O(log⁡N)O(\log N)O(logN).

Worst Case

O(log⁡N)O(\log N)O(logN) addNum.

Binary Heap Priority Queue Tree

Binary Heap Priority Queue Tree
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "find median from data stream", "addNum in O(log N)", "findMedian in O(1)". The median is the value splitting an ordered dataset into two equal halves. Maintaining a sorted array requires O(N)O(N)O(N) insertion. A Senior SWE immediately applies Two Balanced Heaps: a max-heap small storing the lower half, and a min-heap large storing the upper half.

CONSTRAINTS & BOUNDS

Up to 5×1045 \times 10^45×104 calls to addNum and findMedian. Time budget: strictly O(log⁡N)O(\log N)O(logN) per insertion and O(1)O(1)O(1) per median lookup. Auxiliary space: O(N)O(N)O(N) across the two heaps.

FAANG PRODUCTION TRAPS & EDGE CASES

small stores negated values, so read its top as -small[0]. The even-count median must be a float average of the two tops.

Core Algorithmic State Invariants

  1. Follow-Up: Every Value in [0, 100]

LeetCode's first follow-up bounds the values to [0, 100]. Then the heaps are not needed: keep a count per value (101 buckets) and a total. addNum is one increment, and findMedian walks at most 101 buckets to the middle position(s), so memory no longer grows with the stream.

  1. Follow-Up: 99% of Values in [0, 100]

The second follow-up lets 1% of values fall outside [0, 100]. With fewer than half the values on either side of the range, the median always lies inside it, so the 101 buckets still find it; values below 0 or above 100 only need to be counted, to know how far into the buckets the middle position is.

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