Bird
Raised Fist0
Interview Prepstacks-monotonic-stackhardAmazonFacebookGoogle

Maximal Rectangle (Matrix to Histogram)

Choose your preparation mode4 modes available
📋
Problem

Imagine you are analyzing satellite images represented as binary matrices, and you want to find the largest rectangular area of clear land (1s) to build a facility.

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. Input: a 2D list of characters '0' or '1'. Output: an integer representing the area of the largest rectangle of 1's.

1 ≤ number of rows ≤ 2001 ≤ number of columns ≤ 200Each element is '0' or '1'
Edge cases: Empty matrix → 0Matrix with all zeros → 0Matrix with all ones → total area
</>
IDE
def maximalRectangle(matrix: list[list[str]]) -> int:public int maximalRectangle(char[][] matrix)int maximalRectangle(vector<vector<char>>& matrix)function maximalRectangle(matrix)
def maximalRectangle(matrix):
    # Write your solution here
    pass
class Solution {
    public int maximalRectangle(char[][] matrix) {
        // Write your solution here
        return 0;
    }
}
#include <vector>
using namespace std;

int maximalRectangle(vector<vector<char>>& matrix) {
    // Write your solution here
    return 0;
}
function maximalRectangle(matrix) {
    // Write your solution here
}
Coming soon
0/9
Common Bugs to Avoid
Wrong: 0Code returns 0 for all inputs due to missing or incorrect histogram height updates.✅ Initialize heights array and update heights row-wise, resetting to zero on '0' cells.
Wrong: Incorrect smaller than expected max areaStack logic misses final cleanup or miscalculates width leading to smaller max area.✅ After processing all bars, pop remaining stack bars and calculate area correctly using width = current_index - stack_top - 1.
Wrong: Larger than possible areaCode does not reset heights on '0' cells, allowing rectangles to span zeros incorrectly.✅ Reset height to zero for columns with '0' in current row before computing largest rectangle.
Wrong: TLE or timeoutUsing brute force O(rows^2*cols^2) approach instead of O(rows*cols) stack-based solution.✅ Implement row-wise histogram and monotonic stack approach for largest rectangle in histogram.
✓
Test Cases
t1_01basic
Input{"matrix":[["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]}
Expected6

The largest rectangle of 1's has area 6, formed in the third row spanning columns 1 to 5.

t1_02basic
Input{"matrix":[["0","1","1","0","1"],["1","1","1","1","1"],["1","1","1","1","0"]]}
Expected8

Largest rectangle area is 8, formed by rows 1-2 and columns 1-4.

t2_01edge
Input{"matrix":[]}
Expected0

Empty matrix has no rectangles, so area is 0.

t2_02edge
Input{"matrix":[["0"]]}
Expected0

Single element matrix with '0' means no rectangle of 1's, area 0.

t2_03edge
Input{"matrix":[["1"]]}
Expected1

Single element matrix with '1' means largest rectangle area is 1.

t3_01corner
Input{"matrix":[["1","1","1","1"],["1","0","0","1"],["1","1","1","1"]]}
Expected4

Largest rectangle is 4, formed by single row of four 1's (top or bottom row).

t3_02corner
Input{"matrix":[["1","1","1","1","1"],["1","1","1","1","1"],["1","1","1","1","1"]]}
Expected15

All ones matrix, largest rectangle is entire matrix area 3*5=15.

t3_03corner
Input{"matrix":[["1","0","1","1","1"],["1","1","1","1","0"],["1","1","1","0","0"],["1","1","0","0","0"]]}
Expected6

Largest rectangle area is 6, formed by rows 0-1 and columns 2-4.

t4_01performance
Input{"matrix":[["1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["0","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["0","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["0","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["0","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],["0","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","0"],["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"]]}
⏱ Performance - must finish in 2000ms

Large 20x20 matrix tests O(rows*cols) solution efficiency; brute force O(rows^2*cols^2) will time out.

Practice

(1/5)
1. Given the following Python code for asteroid collision, what is the output when the input is [8, -8, 5, -10]?
def asteroidCollision(asteroids):
    stack = []
    for a in asteroids:
        alive = True
        while alive and stack and stack[-1] > 0 and a < 0:
            if stack[-1] < -a:
                stack.pop()
            elif stack[-1] == -a:
                stack.pop()
                alive = False
            else:
                alive = False
        if alive:
            stack.append(a)
    return stack

print(asteroidCollision([8, -8, 5, -10]))
easy
A. [5, -10]
B. [-10]
C. [8, 5, -10]
D. []

Solution

  1. Step 1: Trace collision between 8 and -8

    8 and -8 are equal size but opposite direction, both explode -> stack empty.
  2. Step 2: Process 5 and then -10

    5 is pushed; -10 collides with 5, since 10 > 5, 5 pops, -10 remains and is pushed.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Final stack contains only [-10] after resolving collisions [OK]
Hint: Equal size opposite asteroids both explode [OK]
Common Mistakes:
  • Forgetting to pop both equal asteroids
  • Appending asteroid after it exploded
  • Not handling multiple collisions in while loop
2. What is the time complexity of the optimized stack simulation algorithm for the asteroid collision problem, given n asteroids in the input list?
medium
A. O(n) because each asteroid is pushed and popped at most once
B. O(n log n) due to sorting implicit in stack operations
C. O(n^2) because each asteroid can cause multiple pops in the stack
D. O(n) for iteration plus O(n) for auxiliary space, total O(n)

Solution

  1. Step 1: Analyze iteration over asteroids

    The algorithm iterates over each asteroid once.
  2. Step 2: Analyze stack operations

    Each asteroid can be pushed once and popped once, so total stack operations are O(n).
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Each asteroid processed at most twice (push/pop) [OK]
Hint: Each asteroid pushed and popped once max [OK]
Common Mistakes:
  • Assuming nested while loop causes O(n^2)
  • Confusing stack operations with sorting
  • Ignoring amortized analysis of stack pops
3. The following code attempts to implement a stack using two queues with a costly push operation:
from collections import deque

class MyStack:
    def __init__(self):
        self.q1 = deque()
        self.q2 = deque()

    def push(self, x: int) -> None:
        self.q2.append(x)
        while self.q1:
            self.q2.append(self.q1.popleft())
        # Missing swap here

    def pop(self) -> int:
        return self.q1.popleft()

    def top(self) -> int:
        return self.q1[0]

    def empty(self) -> bool:
        return not self.q1
What is the subtle bug in this code?
medium
A. The push method is missing swapping q1 and q2 after transferring elements.
B. The empty method should check both q1 and q2 for emptiness.
C. The top method should peek at q2 instead of q1.
D. The pop method should dequeue from q2 instead of q1.

Solution

  1. Step 1: Analyze push method

    Elements are moved from q1 to q2, but q1 and q2 are never swapped, so q1 remains empty after push.
  2. Step 2: Consequence on pop and top

    Pop and top operate on q1, which is empty, causing errors or incorrect behavior.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Swapping queues after push is essential to maintain main queue reference [OK]
Hint: Missing queue swap after push breaks main queue reference [OK]
Common Mistakes:
  • Forgetting to swap queues after push
  • Accessing wrong queue in pop or top
  • Checking emptiness incorrectly
4. What is the time complexity of the optimal monotonic stack solution for the Largest Rectangle in Histogram problem, and why?
medium
A. O(n) because each bar is pushed and popped at most once from the stack
B. O(n) but with O(n^2) worst-case due to stack operations
C. O(n^2) because nested loops are used to find boundaries
D. O(n log n) because each element is pushed and popped multiple times

Solution

  1. Step 1: Analyze stack operations

    Each bar is pushed once and popped at most once, so total stack operations are O(n).
  2. Step 2: Confirm no nested loops over all elements

    Loops run linearly, no repeated scanning of all elements inside inner loops.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Linear time complexity due to amortized stack operations [OK]
Hint: Each element pushed/popped once -> O(n) time [OK]
Common Mistakes:
  • Assuming stack operations cause O(n log n) or O(n^2)
  • Confusing nested loops in brute force with stack approach
5. What is the time complexity of the optimal monotonic stack solution for the online stock span problem when processing n prices?
medium
A. O(n) amortized because each element is pushed and popped at most once
B. O(n^2) due to nested while loop popping multiple elements
C. O(n log n) due to binary search within the stack for span calculation
D. O(n) worst-case but O(n^2) average due to repeated stack operations

Solution

  1. Step 1: Analyze stack operations

    Each price index is pushed exactly once and popped at most once from the stack.
  2. Step 2: Calculate amortized complexity

    Since each element is pushed and popped once, total operations are O(n), making the algorithm O(n) amortized time.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Monotonic stack amortized analysis is standard for O(n) [ERROR]
Hint: Each element pushed and popped once -> O(n) amortized [ERROR]
Common Mistakes:
  • Assuming nested loop causes O(n^2)
  • Thinking binary search is used in stack
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard