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•Stack
HardLC 84

Largest Rectangle in Histogram (LeetCode 84)

Target Frequency:GoogleAppleNetflix

You're given an array of integers heights, each entry the height of one histogram bar; every bar has width 1. Return the area of the largest rectangle you can draw that fits entirely inside the histogram's outline.

Worked Examples

Example 1
Input:heights = [2,1,5,6,2,3]
Output:10
201152632435largest rectangle: 2 wide x 5 high = 10
Explanation: Bars at index 2 and 3 (heights 5 and 6) span a width-2 strip at height 5, giving area 5 x 2 = 10, the largest rectangle in this histogram.
Example 2
Input:heights = [2,4]
Output:4
2041largest rectangle: 1 wide x 4 high = 4
Explanation: The bar of height 4 alone, or both bars at height 2, gives area 4.

⚖️Formal Constraints & Bounds

  • 1 <= heights.length <= 105

  • 0 <= heights[i] <= 104

Deep-Dive & Conceptual Insights

Core Insight

Pushing the extended start index backwards when popping shorter bars accounts for full horizontal expansion.

Real-World Scenario & Production Applications

Maximal matrix rectangle detection in computer vision, silhouette bounding area extraction.

Step-by-Step Execution Trace Table

StepBar Index iHeight hStack ActionPopped (idx, h)Width (i−prev_idxi - \text{prev\_idx}i−prev_idx)AreaRunning Max Area
102Push (0, 2)---0
211Pop (0, 2), Push (0, 1)(0, 2)1−0=11 - 0 = 11−0=12×1=22 \times 1 = 22×1=22
325Push (2, 5)---2
436Push (3, 6)---2
542Pop (3, 6)(3, 6)4−3=14 - 3 = 14−3=16×1=66 \times 1 = 66×1=66
Pop (2, 5), Push (2, 2)(2, 5)4−2=24 - 2 = 24−2=25×2=105 \times 2 = \mathbf{10}5×2=1010
653Push (5, 3)---10
76 (Sentinel)0Pop (5, 3)(5, 3)6−5=16 - 5 = 16−5=13×1=33 \times 1 = 33×1=310
Pop (2, 2)(2, 2)6−2=46 - 2 = 46−2=42×4=82 \times 4 = 82×4=810
Pop (0, 1)(0, 1)6−0=66 - 0 = 66−0=61×6=61 \times 6 = 61×6=610
Code Shape
Archetype Code Shape
Python
1extended_heights = heights + [0]
2stack = [-1]
3max_area = 0
4for i, h in enumerate(extended_heights):
5 while stack[-1] != -1 and extended_heights[stack[-1]] >= h:
6 popped_height = extended_heights[stack.pop()]
7 width = i - stack[-1] - 1
8 max_area = max(max_area, popped_height * width)
9 stack.append(i)
10return max_area

Conceptual Narrative

Every candidate rectangle in a histogram is bounded by its shortest bar. A monotonic increasing stack finds each bar's left and right boundary limits, computing all maximal rectangles in O(N) time.

🧭 Conceptual Foundation & Pattern Intuition

For any bar iii with height h=heights[i]h = \text{heights}[i]h=heights[i], what is the largest rectangle that uses bar iii as its limiting height? The rectangle can extend horizontally to the left until it hits the first bar strictly shorter than hhh (Nearest Smaller to Left, NSL), and to the right until it hits the first bar strictly shorter than hhh (Nearest Smaller to Right, NSR). If NSL is at index LLL and NSR is at index RRR, the width is W=R−L−1W = R - L - 1W=R−L−1, and the area is h×(R−L−1)h \times (R - L - 1)h×(R−L−1). A Monotonic Increasing Stack computes this for all bars simultaneously:

  • The stack stores indices of bars in strictly increasing height order.
  • When an incoming bar iii is shorter than the bar at stack[-1], bar iii serves as the NSR (right boundary) for the popped bar.
  • Once popped, the new stack top stack[-1] is the NSL (left boundary) for that popped bar!
  • The Sentinel Trick: Appending a virtual bar of height 0 at the end of the array guarantees that every single bar remaining on the stack is forced to pop and calculate its area, eliminating post-loop cleanup code. A second sentinel, -1 at the bottom of the stack, is the left boundary of any bar with no shorter bar before it, so the width is always i - stack[-1] - 1.
🏗️ The Analogy: Concrete Pillars Supporting an Overhead Roof

Imagine structural pillars lined up in a row. A bridge roof can rest across consecutive pillars at height HHH, but only if every supporting pillar in that span is at least HHH tall. As long as each new pillar is taller than the last, the potential roof height keeps climbing. But the moment a short pillar appears, it caps the horizontal span of all taller pillars before it! Those taller pillars are popped off the design clipboard, their maximal roof spans are calculated, and the shorter pillar becomes the new anchor.

🔑 Why It Works

The sentinel height 0 ensures that the final state leaves only the -1 sentinel on the stack, evaluating all possible rectangular spans in a clean, unified loop running in O(N)O(N)O(N) time and O(N)O(N)O(N) auxiliary memory.

  • Forgetting the sentinel 0 boundary: If the histogram is strictly increasing (e.g. [1, 2, 3, 4]), no elements are ever popped during the loop. Appending a sentinel 0 (heights + [0]) or running a cleanup loop is mandatory to flush the stack.

  • Incorrect width calculation for the leftmost bar: a popped bar with no shorter bar before it spans back to index 0. The -1 sentinel at the bottom of the stack makes i - stack[-1] - 1 give that width (i); without it the width needs a separate empty-stack case.

  • Storing heights instead of indices on the stack: Pushing bar heights instead of bar indices prevents determining how far left the rectangle can extend.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"The area of the largest rectangle in the histogram": every rectangle is as tall as its lowest bar, so each bar's best rectangle spreads left and right until a lower bar stops it.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule: while extended_heights[stack[-1]] >= h, pop the top; its rectangle ends just before i on the right and just after the new stack[-1] on the left.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Measuring the width from the popped index (i - popped_index) or before the pop: bars popped earlier also sat between the new top and i, so the left edge is the new stack[-1] after the pop. On [2, 1, 2] the popped-index width returns 2 instead of 3.

  • Dropping stack[-1] != -1 from the while condition: extended_heights[-1] is the sentinel 0, so a 0 bar pops the -1 floor and the next stack[-1] fails on an empty list.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use a Histogram Stack. I keep bar indices on a stack with heights strictly increasing, and minus one at the bottom as the left wall. When a bar arrives that is not taller than the top, each bar I pop has found its right edge, the current index, and its left edge is the new top after the pop, the nearest lower bar on its left. So its widest rectangle is its height times i minus the new top minus one. The largest rectangle is the widest rectangle of its own lowest bar, so checking every bar once finds it. The trap is measuring the width from the popped index, which leaves out the bars popped earlier. A zero appended at the end pops whatever is left. Each index is pushed and popped once, so it is O(N) time and O(N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the execution steps: the for loop visits the N + 1 entries of extended_heights once. Each index is pushed once by stack.append(i) and popped at most once by stack.pop(), so the while loop runs at most N + 1 times over the whole scan, each time in O(1).

SPACE COMPLEXITY

O(N) Auxiliary

Look at memory allocations: extended_heights is a copy of size N + 1 and stack holds at most N + 1 entries (the -1 included), so O(N). The output is one integer.

Formal Recurrence Relation

∑(push+pop)≤2(N+1)  ⟹  O(N)\sum (\text{push} + \text{pop}) \le 2(N + 1) \implies O(N)∑(push+pop)≤2(N+1)⟹O(N)

Derivation Progression

Push Each Index

stack.append(i)

Every index of extended_heights is pushed exactly once: N + 1 pushes.

Pop and Measure

width = i - stack[-1] - 1

Each pop measures one bar's widest rectangle, popped_height * width, in O(1).

Amortized Bound

≤ 2(N + 1) total stack ops

An index can only be popped after it was pushed, so pops never outnumber pushes.

Variable Definitions

NNN

Total number of vertical bars in the histogram

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(N) extended_heights copy and the index stack

🟢 Output Space

O(1) Max area integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N)

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N)

Recurrence Tree Topology

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

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "largest rectangle in the histogram". A bar of height HHH can bound a rectangle horizontally as far left and right as adjacent bars remain ≥H\ge H≥H, so its edges are the nearest lower bar on each side. The Histogram Stack finds both edges for every bar in one pass.

CONSTRAINTS & BOUNDS

1≤heights.length≤1051 \le heights.length \le 10^51≤heights.length≤105 and 0≤heights[i]≤1040 \le heights[i] \le 10^40≤heights[i]≤104, so an area is at most 10910^9109 and fits in a 32-bit signed integer. Time budget: O(N)O(N)O(N).

FAANG PRODUCTION TRAPS & EDGE CASES

heights + [0] copies the whole input. On very large arrays, loop i from 0 to N and read h = heights[i] if i < N else 0: the same flush without the O(N)O(N)O(N) copy, and still without changing the caller's list.

Core Algorithmic State Invariants

  1. One Rectangle per Bar Is Enough

The largest rectangle has a lowest bar somewhere inside it, and that bar's widest rectangle is at least as large. Every index leaves stack exactly once and is measured when it leaves, so checking one rectangle per bar is guaranteed to find the answer.

  1. Both Nearest-Lower Neighbours in One Pass

At the moment a bar is popped, i is the nearest lower bar on its right and the new stack[-1] the nearest lower bar on its left. Any question about how far each value reaches before a smaller one stops it can reuse these two numbers, as in Maximum Subarray Min-Product (LC 1856).

Theory Context•Stack
HardLC 84

Largest Rectangle in Histogram (LeetCode 84)

Target Frequency:GoogleAppleNetflix

You're given an array of integers heights, each entry the height of one histogram bar; every bar has width 1. Return the area of the largest rectangle you can draw that fits entirely inside the histogram's outline.

Worked Examples

Example 1
Input:heights = [2,1,5,6,2,3]
Output:10
201152632435largest rectangle: 2 wide x 5 high = 10
Explanation: Bars at index 2 and 3 (heights 5 and 6) span a width-2 strip at height 5, giving area 5 x 2 = 10, the largest rectangle in this histogram.
Example 2
Input:heights = [2,4]
Output:4
2041largest rectangle: 1 wide x 4 high = 4
Explanation: The bar of height 4 alone, or both bars at height 2, gives area 4.

⚖️Formal Constraints & Bounds

  • 1 <= heights.length <= 105

  • 0 <= heights[i] <= 104

Deep-Dive & Conceptual Insights

Core Insight

Pushing the extended start index backwards when popping shorter bars accounts for full horizontal expansion.

Real-World Scenario & Production Applications

Maximal matrix rectangle detection in computer vision, silhouette bounding area extraction.

Step-by-Step Execution Trace Table

StepBar Index iHeight hStack ActionPopped (idx, h)Width (i−prev_idxi - \text{prev\_idx}i−prev_idx)AreaRunning Max Area
102Push (0, 2)---0
211Pop (0, 2), Push (0, 1)(0, 2)1−0=11 - 0 = 11−0=12×1=22 \times 1 = 22×1=22
325Push (2, 5)---2
436Push (3, 6)---2
542Pop (3, 6)(3, 6)4−3=14 - 3 = 14−3=16×1=66 \times 1 = 66×1=66
Pop (2, 5), Push (2, 2)(2, 5)4−2=24 - 2 = 24−2=25×2=105 \times 2 = \mathbf{10}5×2=1010
653Push (5, 3)---10
76 (Sentinel)0Pop (5, 3)(5, 3)6−5=16 - 5 = 16−5=13×1=33 \times 1 = 33×1=310
Pop (2, 2)(2, 2)6−2=46 - 2 = 46−2=42×4=82 \times 4 = 82×4=810
Pop (0, 1)(0, 1)6−0=66 - 0 = 66−0=61×6=61 \times 6 = 61×6=610
Code Shape
Archetype Code Shape
Python
1extended_heights = heights + [0]
2stack = [-1]
3max_area = 0
4for i, h in enumerate(extended_heights):
5 while stack[-1] != -1 and extended_heights[stack[-1]] >= h:
6 popped_height = extended_heights[stack.pop()]
7 width = i - stack[-1] - 1
8 max_area = max(max_area, popped_height * width)
9 stack.append(i)
10return max_area

Conceptual Narrative

Every candidate rectangle in a histogram is bounded by its shortest bar. A monotonic increasing stack finds each bar's left and right boundary limits, computing all maximal rectangles in O(N) time.

🧭 Conceptual Foundation & Pattern Intuition

For any bar iii with height h=heights[i]h = \text{heights}[i]h=heights[i], what is the largest rectangle that uses bar iii as its limiting height? The rectangle can extend horizontally to the left until it hits the first bar strictly shorter than hhh (Nearest Smaller to Left, NSL), and to the right until it hits the first bar strictly shorter than hhh (Nearest Smaller to Right, NSR). If NSL is at index LLL and NSR is at index RRR, the width is W=R−L−1W = R - L - 1W=R−L−1, and the area is h×(R−L−1)h \times (R - L - 1)h×(R−L−1). A Monotonic Increasing Stack computes this for all bars simultaneously:

  • The stack stores indices of bars in strictly increasing height order.
  • When an incoming bar iii is shorter than the bar at stack[-1], bar iii serves as the NSR (right boundary) for the popped bar.
  • Once popped, the new stack top stack[-1] is the NSL (left boundary) for that popped bar!
  • The Sentinel Trick: Appending a virtual bar of height 0 at the end of the array guarantees that every single bar remaining on the stack is forced to pop and calculate its area, eliminating post-loop cleanup code. A second sentinel, -1 at the bottom of the stack, is the left boundary of any bar with no shorter bar before it, so the width is always i - stack[-1] - 1.
🏗️ The Analogy: Concrete Pillars Supporting an Overhead Roof

Imagine structural pillars lined up in a row. A bridge roof can rest across consecutive pillars at height HHH, but only if every supporting pillar in that span is at least HHH tall. As long as each new pillar is taller than the last, the potential roof height keeps climbing. But the moment a short pillar appears, it caps the horizontal span of all taller pillars before it! Those taller pillars are popped off the design clipboard, their maximal roof spans are calculated, and the shorter pillar becomes the new anchor.

🔑 Why It Works

The sentinel height 0 ensures that the final state leaves only the -1 sentinel on the stack, evaluating all possible rectangular spans in a clean, unified loop running in O(N)O(N)O(N) time and O(N)O(N)O(N) auxiliary memory.

  • Forgetting the sentinel 0 boundary: If the histogram is strictly increasing (e.g. [1, 2, 3, 4]), no elements are ever popped during the loop. Appending a sentinel 0 (heights + [0]) or running a cleanup loop is mandatory to flush the stack.

  • Incorrect width calculation for the leftmost bar: a popped bar with no shorter bar before it spans back to index 0. The -1 sentinel at the bottom of the stack makes i - stack[-1] - 1 give that width (i); without it the width needs a separate empty-stack case.

  • Storing heights instead of indices on the stack: Pushing bar heights instead of bar indices prevents determining how far left the rectangle can extend.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"The area of the largest rectangle in the histogram": every rectangle is as tall as its lowest bar, so each bar's best rectangle spreads left and right until a lower bar stops it.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule: while extended_heights[stack[-1]] >= h, pop the top; its rectangle ends just before i on the right and just after the new stack[-1] on the left.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Measuring the width from the popped index (i - popped_index) or before the pop: bars popped earlier also sat between the new top and i, so the left edge is the new stack[-1] after the pop. On [2, 1, 2] the popped-index width returns 2 instead of 3.

  • Dropping stack[-1] != -1 from the while condition: extended_heights[-1] is the sentinel 0, so a 0 bar pops the -1 floor and the next stack[-1] fails on an empty list.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use a Histogram Stack. I keep bar indices on a stack with heights strictly increasing, and minus one at the bottom as the left wall. When a bar arrives that is not taller than the top, each bar I pop has found its right edge, the current index, and its left edge is the new top after the pop, the nearest lower bar on its left. So its widest rectangle is its height times i minus the new top minus one. The largest rectangle is the widest rectangle of its own lowest bar, so checking every bar once finds it. The trap is measuring the width from the popped index, which leaves out the bars popped earlier. A zero appended at the end pops whatever is left. Each index is pushed and popped once, so it is O(N) time and O(N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the execution steps: the for loop visits the N + 1 entries of extended_heights once. Each index is pushed once by stack.append(i) and popped at most once by stack.pop(), so the while loop runs at most N + 1 times over the whole scan, each time in O(1).

SPACE COMPLEXITY

O(N) Auxiliary

Look at memory allocations: extended_heights is a copy of size N + 1 and stack holds at most N + 1 entries (the -1 included), so O(N). The output is one integer.

Formal Recurrence Relation

∑(push+pop)≤2(N+1)  ⟹  O(N)\sum (\text{push} + \text{pop}) \le 2(N + 1) \implies O(N)∑(push+pop)≤2(N+1)⟹O(N)

Derivation Progression

Push Each Index

stack.append(i)

Every index of extended_heights is pushed exactly once: N + 1 pushes.

Pop and Measure

width = i - stack[-1] - 1

Each pop measures one bar's widest rectangle, popped_height * width, in O(1).

Amortized Bound

≤ 2(N + 1) total stack ops

An index can only be popped after it was pushed, so pops never outnumber pushes.

Variable Definitions

NNN

Total number of vertical bars in the histogram

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(N) extended_heights copy and the index stack

🟢 Output Space

O(1) Max area integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N)

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N)

Recurrence Tree Topology

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

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "largest rectangle in the histogram". A bar of height HHH can bound a rectangle horizontally as far left and right as adjacent bars remain ≥H\ge H≥H, so its edges are the nearest lower bar on each side. The Histogram Stack finds both edges for every bar in one pass.

CONSTRAINTS & BOUNDS

1≤heights.length≤1051 \le heights.length \le 10^51≤heights.length≤105 and 0≤heights[i]≤1040 \le heights[i] \le 10^40≤heights[i]≤104, so an area is at most 10910^9109 and fits in a 32-bit signed integer. Time budget: O(N)O(N)O(N).

FAANG PRODUCTION TRAPS & EDGE CASES

heights + [0] copies the whole input. On very large arrays, loop i from 0 to N and read h = heights[i] if i < N else 0: the same flush without the O(N)O(N)O(N) copy, and still without changing the caller's list.

Core Algorithmic State Invariants

  1. One Rectangle per Bar Is Enough

The largest rectangle has a lowest bar somewhere inside it, and that bar's widest rectangle is at least as large. Every index leaves stack exactly once and is measured when it leaves, so checking one rectangle per bar is guaranteed to find the answer.

  1. Both Nearest-Lower Neighbours in One Pass

At the moment a bar is popped, i is the nearest lower bar on its right and the new stack[-1] the nearest lower bar on its left. Any question about how far each value reaches before a smaller one stops it can reuse these two numbers, as in Maximum Subarray Min-Product (LC 1856).

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