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).

12 Core Algorithmic Patterns & 168 Practice Problems

  • 1. Two Pointers (9 Paradigms, 32 Problems): Converging pointers, sorted pair sums, container with most water, trapping rain water, 3Sum, plus the Sliding Window and Fast & Slow Pointers paradigms (Floyd cycle detection, monotonic window invariants, longest substrings, minimum window).
  • 2. Binary Search (8 Paradigms, 12 Problems): Monotonic predicate partitioning, boundary searching, rotated arrays, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (5 Paradigms, 8 Problems): Bitmasking, XOR tricks, counting set bits, subset enumeration via bitmasks.
  • 4. Math & Geometry (5 Paradigms, 10 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (8 Paradigms, 17 Problems): Path sums, lowest common ancestor, tree diameter, subtree serialization, validating BSTs.
  • 6. Tree/Graph Breadth-First Search (4 Paradigms, 11 Problems): Level-order traversals, shortest path, rotting oranges, word ladders.
  • 7. Graphs (6 Paradigms, 14 Problems): Topological sort, cycle detection, Dijkstra, bipartite validation, network delay.
  • 8. Backtracking (5 Paradigms, 13 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens.
  • 9. Dynamic Programming (7 Paradigms, 14 Problems): Memoization vs tabulation, knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (8 Paradigms, 10 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (5 Paradigms, 13 Problems): Trie, Union-Find, LRU Cache, LFU Cache, Monotonic Stacks.
  • 12. Intervals & Stack / Miscellaneous (7 Paradigms, 14 Problems): Merge intervals, daily temperatures, largest rectangle in histogram, trapping rain water via stack.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Multi-language Rosetta Stone contrasting abstract invariants with concrete solutions across Python, C#, Java, TypeScript, C++, Go, and Rust.
  2. Stage 2 (Active Recall): Reconstruct algorithmic template invariants from memory with real-time feedback before looking at solutions.
  3. Stage 3 (Senior SWE AI Mock Coach): Simulated senior mock interview evaluating Big-O space/time tradeoffs, edge cases, and code reviews in Monaco Editor.
  4. Stage 4 (Solve on Your Own): Timed sandbox challenges verified against automated test suites in Python, C#, Java, and TypeScript.

Equipped with SM-2 Spaced Repetition Review Hub, Studio Cockpit workspace layout, and interactive study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Compute Coins: 40 free coins upon signup, +20 daily login bonus, +25 referral bonus.
  • 24-Hour AI Coaching Pass: 5 compute coins unlocks unlimited senior SWE AI coaching for a full 24 hours.
  • BYOK (Bring Your Own Key): Completely free unlimited AI coaching if using your own Gemini/OpenAI API key.
  • Refund & Subscription Policy: No recurring charges, no subscription traps, and no paid paywalls. Free tier provides full learning path.
  • Platform Operator: Hi👋WebEnterprise Inc. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

180Items
Theory Context•Two Pointers & Sliding Window
MediumLC 503

Next Greater Element II (LeetCode 503)

Isomorphic Mapping from Circular Loops to Linear Windows

Target Frequency:GoogleAppleAmazonMicrosoft

Given a sorted sequence of unknown, unbounded, or infinite size, search for a target value in O(log⁡k)O(\log k)O(logk) time, where kkk is the target's index.

The Technique Invariant: When the upper bound nnn is unknown or unbounded, standard binary search cannot establish initial [0,n−1][0, n-1][0,n−1] pointers, while linear scanning requires O(k)O(k)O(k) time. Apply Virtual Doubling (Galloping Search):

  • Start with an exponential probe step of step=1step = 1step=1.
  • Repeatedly double the probe index (1,2,4,8,…,2p1, 2, 4, 8, \dots, 2^p1,2,4,8,…,2p) until arr[2p]≥targetarr[2^p] \ge targetarr[2p]≥target or an out-of-bounds boundary is encountered.
  • The target is now strictly bounded within the finite interval [2p−1,2p][2^{p-1}, 2^p][2p−1,2p] after O(log⁡k)O(\log k)O(logk) probes.
  • Run standard binary search exclusively within that localized window in O(log⁡k)O(\log k)O(logk) time. Total search cost is compressed to O(log⁡k)O(\log k)O(logk) with O(1)O(1)O(1) auxiliary space.

Worked Examples

Example 1
Input:nums = [1,2,1]
Output:[2,-1,2]
Explanation: The first `1` sees `2` next. Nothing is bigger than `2`, so it gets `-1`. The last `1` wraps around to the start and finds `2`.
Example 2
Input:nums = [1,2,3,4,3]
Output:[2,3,4,-1,4]
Explanation: `4` is the largest value, so it gets `-1`. The final `3` wraps around and finds `4`.

⚖️Formal Constraints & Bounds

  • 1 <= nums.length <= 10^4

  • -10^9 <= nums[i] <= 10^9

Deep-Dive & Conceptual Insights

Why It Works & Core Invariant

2^{p-1} < k ≤ 2^p ⟹ Target is bounded within [2^{p-1}, 2^p] after p = ⌈\log_2 k⌉ probes.

Real-World Scenario & Production Applications

Kafka consumer group partition assignment and token ring networks use virtual doubling to calculate next partition handoffs without loop branching.

Core Invariant Specification & Code Shape
Archetype Code Shape
Python
1Iterate through a virtual range of 2 * N - 1 steps
2Access elements via modulo index: nums[i % n]
3Maintain a monotonic decreasing index stack
4Only record answers when i < n

Target: Next Greater Element II (LeetCode 503). Double traversal range simulates wrap-around without allocating memory copies of the array in heap space.

Boundary Model: Virtual Modulo Bound [0, 2N - 1)

Loop index runs from 0 to 2N - 1. Physical array access is mapped via i % N. Push indices to monotonic stack only during the first pass (i < N).

Loop Invariant Termination

for i in range(2 * n - 1, -1, -1) or for i in range(2 * n): val = nums[i % n]

Conceptual Narrative

The Flash of Genius: Circular arrays break index bounds and require awkward wrapping logic. By virtually concatenating the array to twice its length (2N) and indexing via i % N, every contiguous circular window becomes a simple linear slice. Monotonic stacks and sliding windows run unmodified.

The Mental Model Analogy: The 12-Hour Circular Clock Face

Imagine looking at a traditional circular clock face. If the hour hand is at 10 and you want to know what time it will be 5 hours from now, you do not throw away the clock and build a special 24-hour straight wooden ruler. You simply count past 12: 10 + 5 = 15, and compute 15 mod 12 = 3 o'clock! The circle naturally wraps around. Now imagine you have an array of elements arranged in a circle, and each element needs to search forward for the next element greater than itself, wrapping past the end of the array back to the beginning. Instead of allocating physical memory to clone the array and create [A | A]—wasting double the RAM and triggering garbage collection—you simply let your loop index run up to 2N - 1, and map every access through index % N! To your algorithm, it looks like a continuous array of length 2N; to your computer's RAM, not a single extra byte was allocated!

  • Pitfall: A circular array of length N is equivalent to unrolling it twice, but physical duplication wastes O(N) memory.

  • Pitfall: The modulo operator i % n simulates a doubled array dynamically in O(1) space.

  • Pitfall: Loop from 2*n - 1 down to 0, maintaining next greater candidates in a monotonic stack.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Senior SWE thought process architecture for Virtual Doubling for Cyclic Arrays.

Pattern Recognition Signals

The 10-second spot

The problem states that the array is circular: the last element wraps around to the first. Reject physical concatenation (nums + nums) to preserve memory.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Because any element can search at most N−1N - 1N−1 positions ahead before wrapping back onto itself, traversing 2N2N2N steps covers all possible search candidates.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Stack condition: while stack and stack[-1] <= curr: stack.pop().

  • Push: stack.append(curr) on every virtual step.

The 60-Second Interview Pitch

Say this out loud before you type a single line

Test on uniform arrays [1,1,1][1, 1, 1][1,1,1] (all return −1-1−1) and strictly decreasing arrays [5,4,3,2,1][5, 4, 3, 2, 1][5,4,3,2,1] (all elements find 555 except 555 itself).

Circular arrays break index bounds and require awkward wrapping logic. By virtually concatenating the array to twice its length (2N) and indexing via i % N, every contiguous circular window becomes a simple linear slice. Monotonic stacks and sliding windows run unmodified.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

The virtual loop executes exactly 2N iterations. In each iteration, an element is pushed onto the monotonic stack once. Across the entire 2N steps, an element can be popped at most 2N times. The total number of stack operations is bounded by 4N. Each operation takes O(1) time. The total runtime is strictly O(2N) = O(N).

SPACE COMPLEXITY

O(N)

No duplicate array buffer is allocated. The stack stores at most N elements at any time. Result array requires N integers. Auxiliary space complexity is strictly O(N).

Formal Recurrence Relation

lim⁡k→∞N2k=1  ⟹  2k=N  ⟹  k=log⁡2N\lim_{k \to \infty} \frac{N}{2^k} = 1 \implies 2^k = N \implies k = \log_2 Nlimk→∞​2kN​=1⟹2k=N⟹k=log2​N

The virtual loop executes exactly 2N iterations. In each iteration, an element is pushed onto the monotonic stack once. Across the entire 2N steps, an element can be popped at most 2N times. The total number of stack operations is bounded by 4N. Each operation takes O(1) time. The total runtime is strictly O(2N) = O(N).

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Rejects nums + nums concatenation, demonstrating concern for memory footprint and garbage collection. • Uses i % n effortlessly within loop conditions. • Explains that a virtual length of 2N is sufficient because an element cannot search past its own starting position. • Identifies bitwise optimization: when N is a power of 2, i % N can be written as i & (N - 1).

CONSTRAINTS & BOUNDS

1 <= nums.length <= 10^4. -10^9 <= nums[i] <= 10^9

FAANG PRODUCTION TRAPS & EDGE CASES

In operating system ring buffers (e.g. Linux kfifo, circular audio buffers), pointers increment infinitely and are masked with & (size - 1) to wrap without branch conditions.

Core Algorithmic State Invariants

1. Monotonic Window Expansion

The right pointer advances forward, absorbing the incoming element into the running aggregation state (frequency map, sum, or set).

2. Window Validity & Contraction Invariant

When window constraints are violated (or while valid when seeking minimal length), the left pointer increments to evict elements and restore the required invariant.

3. Amortized Linear Termination

Because each element enters and exits the window at most once, total operations across both pointers are bounded by 2N, guaranteeing strictly linear O(N) execution.

Theory Context•Two Pointers & Sliding Window
MediumLC 503

Next Greater Element II (LeetCode 503)

Isomorphic Mapping from Circular Loops to Linear Windows

Target Frequency:GoogleAppleAmazonMicrosoft

Given a sorted sequence of unknown, unbounded, or infinite size, search for a target value in O(log⁡k)O(\log k)O(logk) time, where kkk is the target's index.

The Technique Invariant: When the upper bound nnn is unknown or unbounded, standard binary search cannot establish initial [0,n−1][0, n-1][0,n−1] pointers, while linear scanning requires O(k)O(k)O(k) time. Apply Virtual Doubling (Galloping Search):

  • Start with an exponential probe step of step=1step = 1step=1.
  • Repeatedly double the probe index (1,2,4,8,…,2p1, 2, 4, 8, \dots, 2^p1,2,4,8,…,2p) until arr[2p]≥targetarr[2^p] \ge targetarr[2p]≥target or an out-of-bounds boundary is encountered.
  • The target is now strictly bounded within the finite interval [2p−1,2p][2^{p-1}, 2^p][2p−1,2p] after O(log⁡k)O(\log k)O(logk) probes.
  • Run standard binary search exclusively within that localized window in O(log⁡k)O(\log k)O(logk) time. Total search cost is compressed to O(log⁡k)O(\log k)O(logk) with O(1)O(1)O(1) auxiliary space.

Worked Examples

Example 1
Input:nums = [1,2,1]
Output:[2,-1,2]
Explanation: The first `1` sees `2` next. Nothing is bigger than `2`, so it gets `-1`. The last `1` wraps around to the start and finds `2`.
Example 2
Input:nums = [1,2,3,4,3]
Output:[2,3,4,-1,4]
Explanation: `4` is the largest value, so it gets `-1`. The final `3` wraps around and finds `4`.

⚖️Formal Constraints & Bounds

  • 1 <= nums.length <= 10^4

  • -10^9 <= nums[i] <= 10^9

Deep-Dive & Conceptual Insights

Why It Works & Core Invariant

2^{p-1} < k ≤ 2^p ⟹ Target is bounded within [2^{p-1}, 2^p] after p = ⌈\log_2 k⌉ probes.

Real-World Scenario & Production Applications

Kafka consumer group partition assignment and token ring networks use virtual doubling to calculate next partition handoffs without loop branching.

Core Invariant Specification & Code Shape
Archetype Code Shape
Python
1Iterate through a virtual range of 2 * N - 1 steps
2Access elements via modulo index: nums[i % n]
3Maintain a monotonic decreasing index stack
4Only record answers when i < n

Target: Next Greater Element II (LeetCode 503). Double traversal range simulates wrap-around without allocating memory copies of the array in heap space.

Boundary Model: Virtual Modulo Bound [0, 2N - 1)

Loop index runs from 0 to 2N - 1. Physical array access is mapped via i % N. Push indices to monotonic stack only during the first pass (i < N).

Loop Invariant Termination

for i in range(2 * n - 1, -1, -1) or for i in range(2 * n): val = nums[i % n]

Conceptual Narrative

The Flash of Genius: Circular arrays break index bounds and require awkward wrapping logic. By virtually concatenating the array to twice its length (2N) and indexing via i % N, every contiguous circular window becomes a simple linear slice. Monotonic stacks and sliding windows run unmodified.

The Mental Model Analogy: The 12-Hour Circular Clock Face

Imagine looking at a traditional circular clock face. If the hour hand is at 10 and you want to know what time it will be 5 hours from now, you do not throw away the clock and build a special 24-hour straight wooden ruler. You simply count past 12: 10 + 5 = 15, and compute 15 mod 12 = 3 o'clock! The circle naturally wraps around. Now imagine you have an array of elements arranged in a circle, and each element needs to search forward for the next element greater than itself, wrapping past the end of the array back to the beginning. Instead of allocating physical memory to clone the array and create [A | A]—wasting double the RAM and triggering garbage collection—you simply let your loop index run up to 2N - 1, and map every access through index % N! To your algorithm, it looks like a continuous array of length 2N; to your computer's RAM, not a single extra byte was allocated!

  • Pitfall: A circular array of length N is equivalent to unrolling it twice, but physical duplication wastes O(N) memory.

  • Pitfall: The modulo operator i % n simulates a doubled array dynamically in O(1) space.

  • Pitfall: Loop from 2*n - 1 down to 0, maintaining next greater candidates in a monotonic stack.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Senior SWE thought process architecture for Virtual Doubling for Cyclic Arrays.

Pattern Recognition Signals

The 10-second spot

The problem states that the array is circular: the last element wraps around to the first. Reject physical concatenation (nums + nums) to preserve memory.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Because any element can search at most N−1N - 1N−1 positions ahead before wrapping back onto itself, traversing 2N2N2N steps covers all possible search candidates.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Stack condition: while stack and stack[-1] <= curr: stack.pop().

  • Push: stack.append(curr) on every virtual step.

The 60-Second Interview Pitch

Say this out loud before you type a single line

Test on uniform arrays [1,1,1][1, 1, 1][1,1,1] (all return −1-1−1) and strictly decreasing arrays [5,4,3,2,1][5, 4, 3, 2, 1][5,4,3,2,1] (all elements find 555 except 555 itself).

Circular arrays break index bounds and require awkward wrapping logic. By virtually concatenating the array to twice its length (2N) and indexing via i % N, every contiguous circular window becomes a simple linear slice. Monotonic stacks and sliding windows run unmodified.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

The virtual loop executes exactly 2N iterations. In each iteration, an element is pushed onto the monotonic stack once. Across the entire 2N steps, an element can be popped at most 2N times. The total number of stack operations is bounded by 4N. Each operation takes O(1) time. The total runtime is strictly O(2N) = O(N).

SPACE COMPLEXITY

O(N)

No duplicate array buffer is allocated. The stack stores at most N elements at any time. Result array requires N integers. Auxiliary space complexity is strictly O(N).

Formal Recurrence Relation

lim⁡k→∞N2k=1  ⟹  2k=N  ⟹  k=log⁡2N\lim_{k \to \infty} \frac{N}{2^k} = 1 \implies 2^k = N \implies k = \log_2 Nlimk→∞​2kN​=1⟹2k=N⟹k=log2​N

The virtual loop executes exactly 2N iterations. In each iteration, an element is pushed onto the monotonic stack once. Across the entire 2N steps, an element can be popped at most 2N times. The total number of stack operations is bounded by 4N. Each operation takes O(1) time. The total runtime is strictly O(2N) = O(N).

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Rejects nums + nums concatenation, demonstrating concern for memory footprint and garbage collection. • Uses i % n effortlessly within loop conditions. • Explains that a virtual length of 2N is sufficient because an element cannot search past its own starting position. • Identifies bitwise optimization: when N is a power of 2, i % N can be written as i & (N - 1).

CONSTRAINTS & BOUNDS

1 <= nums.length <= 10^4. -10^9 <= nums[i] <= 10^9

FAANG PRODUCTION TRAPS & EDGE CASES

In operating system ring buffers (e.g. Linux kfifo, circular audio buffers), pointers increment infinitely and are masked with & (size - 1) to wrap without branch conditions.

Core Algorithmic State Invariants

1. Monotonic Window Expansion

The right pointer advances forward, absorbing the incoming element into the running aggregation state (frequency map, sum, or set).

2. Window Validity & Contraction Invariant

When window constraints are violated (or while valid when seeking minimal length), the left pointer increments to evict elements and restore the required invariant.

3. Amortized Linear Termination

Because each element enters and exits the window at most once, total operations across both pointers are bounded by 2N, guaranteeing strictly linear O(N) execution.

Rosetta Dual-Monaco Comparison
Python 3
CANONICAL INVARIANT TEMPLATE
Loading...
CONCRETE: NEXT GREATER ELEMENT II (LEETCODE 503)
T = O(N)S = O(N)
Loading...
Pattern Implementation Mapping TableCanonical Invariant ⟷ Concrete Code ⟷ Engineering Rationale
Canonical InvariantConcrete CodeEngineering Rationale
for i in range(2 * n - 1, -1, -1):for i in range(2 * n - 1, -1, -1):Double traversal range simulates wrap-around without allocating memory copies of the array in heap space.
curr_val = nums[i % n]curr_val = nums[i % n]Modulo mapping projects virtual indices [0..2n-1] onto valid physical positions [0..n-1].
if i < n and stack: result[i] = nums[stack[-1]]if i < n and stack: result[i] = nums[stack[-1]]Pass 1 (i >= n) warms up the monotonic stack with suffix elements; Pass 2 (i < n) records answers.
© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•