Bird
Raised Fist0
Interview Prepchallenge-problemshardAmazonFacebookGoogleBloomberg

Largest Rectangle in Histogram

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize stack and max_area

We start with an empty stack and max_area set to 0. The input array is extended by appending a sentinel 0 height to ensure all bars are processed.

💡 Initializing max_area and stack prepares us to track the largest rectangle and the indices of bars in ascending height order.
Line:stack = [] max_area = 0 heights.append(0)
💡 The sentinel 0 at the end guarantees the stack will be emptied by the end of iteration.
📊
Largest Rectangle in Histogram - Watch the Algorithm Execute, Step by Step
Watching the stack operations and area calculations visually reveals how the algorithm efficiently finds the largest rectangle without checking all sub-rectangles.
Step 1/20
·Active fill★Answer cell
setup
2
0
1
1
5
2
6
3
2
4
3
5
0
6
Result: 0
move_right
stack
2
0
1
1
5
2
6
3
2
4
3
5
0
6
Result: 0
pop
2
0
i
1
1
5
2
6
3
2
4
3
5
0
6
Result: 0
record
2
0
i
1
1
5
2
6
3
2
4
3
5
0
6
Result: 2
move_right
2
0
stack
1
1
5
2
6
3
2
4
3
5
0
6
Result: 2
move_right
2
0
1
1
stack
5
2
6
3
2
4
3
5
0
6
Result: 2
move_right
2
0
1
1
5
2
stack
6
3
2
4
3
5
0
6
Result: 2
pop
2
0
1
1
stack
5
2
6
3
i
2
4
3
5
0
6
Result: 2
record
2
0
1
1
stack
5
2
6
3
i
2
4
3
5
0
6
Result: 6
pop
2
0
stack
1
1
5
2
6
3
i
2
4
3
5
0
6
Result: 6
record
2
0
stack
1
1
5
2
6
3
i
2
4
3
5
0
6
Result: 10
move_right
2
0
1
1
5
2
6
3
stack
2
4
3
5
0
6
Result: 10
move_right
2
0
1
1
5
2
6
3
2
4
stack
3
5
0
6
Result: 10
pop
2
0
1
1
5
2
6
3
stack
2
4
3
5
i
0
6
Result: 10
record
2
0
1
1
5
2
6
3
stack
2
4
3
5
i
0
6
Result: 10
pop
2
0
stack
1
1
5
2
6
3
2
4
3
5
i
0
6
Result: 10
record
2
0
stack
1
1
5
2
6
3
2
4
3
5
i
0
6
Result: 10
pop
2
0
1
1
5
2
6
3
2
4
3
5
i
0
6
Result: 10
record
2
0
1
1
5
2
6
3
2
4
3
5
i
0
6
Result: 10
return
2
0
1
1
5
2
6
3
2
4
3
5
Result: 10

Key Takeaways

✓ The stack maintains indices of bars in ascending height order, enabling efficient area calculations.

This insight is hard to see from code alone because the stack operations and their purpose are implicit without visualization.

✓ Popping bars when a shorter bar is encountered finalizes the largest rectangle for those bars.

Visualizing the popping and area calculation clarifies why the algorithm doesn't need to check all sub-rectangles.

✓ The sentinel 0 height at the end ensures all bars are processed and the stack is emptied.

Without the sentinel, the algorithm would need extra logic to finalize remaining bars; the sentinel simplifies the process.

Practice

(1/5)
1. Consider the following Python code implementing the optimal DP solution for the stock problem with k transactions. What is the final output when calling maxProfit(1, [1, 5, 2])?
def maxProfit(k, prices):
    n = len(prices)
    if k >= n // 2:
        profit = 0
        for i in range(1, n):
            profit += max(0, prices[i] - prices[i - 1])
        return profit
    next_dp = [[0, 0] for _ in range(k + 1)]
    curr_dp = [[0, 0] for _ in range(k + 1)]
    for i in range(n - 1, -1, -1):
        for t in range(1, k + 1):
            curr_dp[t][0] = max(-prices[i] + next_dp[t][1], next_dp[t][0])
            curr_dp[t][1] = max(prices[i] + next_dp[t - 1][0], next_dp[t][1])
        next_dp, curr_dp = curr_dp, next_dp
    return next_dp[k][0]

print(maxProfit(1, [1, 5, 2]))
easy
A. 4
B. 5
C. 3
D. 1

Solution

  1. Step 1: Trace dp for i=2 (price=2), t=1

    Initialize next_dp and curr_dp with zeros. At i=2, curr_dp[1][0] = max(-2 + next_dp[1][1], next_dp[1][0]) = max(-2 + 0, 0) = 0; curr_dp[1][1] = max(2 + next_dp[0][0], next_dp[1][1]) = max(2 + 0, 0) = 2.
  2. Step 2: Trace dp for i=1 (price=5), t=1

    curr_dp[1][0] = max(-5 + next_dp[1][1], next_dp[1][0]) = max(-5 + 2, 0) = 0; curr_dp[1][1] = max(5 + next_dp[0][0], next_dp[1][1]) = max(5 + 0, 2) = 5.
  3. Step 3: Trace dp for i=0 (price=1), t=1

    curr_dp[1][0] = max(-1 + next_dp[1][1], next_dp[1][0]) = max(-1 + 5, 0) = 4; curr_dp[1][1] = max(1 + next_dp[0][0], next_dp[1][1]) = max(1 + 0, 5) = 5.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Maximum profit with 1 transaction is buying at 1 and selling at 5 -> profit 4 [OK]
Hint: Trace dp arrays backward to find max profit [OK]
Common Mistakes:
  • Confusing holding and not holding states
  • Off-by-one errors in indexing transactions
  • Misreading the final dp state to return
2. You need to transform one string into another using the minimum number of insertions, deletions, and substitutions. Which algorithmic approach guarantees finding the optimal solution efficiently?
easy
A. Greedy algorithm that replaces characters whenever they differ
B. Pure brute force recursion without memoization
C. Dynamic Programming that builds a table of subproblem solutions based on prefixes
D. Divide and conquer by splitting strings into halves and solving independently

Solution

  1. Step 1: Understand problem requires minimum edits

    The problem asks for minimum insertions, deletions, and substitutions to convert one string to another, which is a classic DP problem.
  2. Step 2: Identify approach guaranteeing optimal substructure

    Dynamic Programming builds solutions for prefixes and combines them, ensuring optimality and polynomial time.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    DP table approach is standard for edit distance [OK]
Hint: Edit distance requires DP over prefixes [OK]
Common Mistakes:
  • Thinking greedy or divide-and-conquer works optimally
3. Given the following code snippet implementing the two-pointer approach for trapping rain water, what is the value of the variable water after the first iteration of the while loop when the input is [2, 0, 2]?
easy
A. 0
B. 2
C. 1
D. 3

Solution

  1. Step 1: Initialize variables

    left=0, right=2, left_max=0, right_max=0, water=0
  2. Step 2: First iteration of while loop

    height[left]=2, height[right]=2, since height[left] is not less than height[right], else branch runs. height[right]=2 ≥ right_max=0, so right_max=2, right decrements to 1, water remains 0.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Water not added on first iteration because max updated [OK]
Hint: Water added only when current height < max height on that side [OK]
Common Mistakes:
  • Adding water before max height is updated
  • Confusing left and right pointer conditions
  • Off-by-one errors in pointer movement
4. Examine the following buggy code snippet for Expression Add Operators. Which line contains the subtle bug that causes incorrect results on inputs with leading zeros?
medium
A. Line appending operator '+': path.append('+')
B. Line checking for leading zero: if i != index and num[index] == '0': break
C. Line converting substring to int: curr = int(curr_str)
D. Line resetting path after recursion: path[:] = path[:length_before]

Solution

  1. Step 1: Identify handling of leading zeros

    The check for leading zeros is inside the else block, after the first index, which is correct placement.
  2. Step 2: Confirm correctness of the check

    The condition "if i != index and num[index] == '0': break" prevents numbers like "05" but is placed after the first index check, which causes it to be skipped for the very first number, allowing invalid leading zeros there.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Leading zero check must be before substring parsing to avoid invalid numbers [OK]
Hint: Leading zero check must be before int conversion and recursion [OK]
Common Mistakes:
  • Placing leading zero check too late
  • Not breaking early on invalid substrings
5. What is the time complexity of the brute force approach for the trapping rain water problem, where for each bar you find the maximum height to the left and right using nested loops?
medium
A. O(n log n)
B. O(n)
C. O(n^2)
D. O(n^3)

Solution

  1. Step 1: Identify loops

    Outer loop runs n times; for each i, two inner loops run up to i and n-i times respectively.
  2. Step 2: Calculate total operations

    Each inner loop can run up to O(n), so total is O(n) * O(n) = O(n²).
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Nested loops over n elements -> quadratic time [OK]
Hint: Nested loops over n elements -> O(n²) time [OK]
Common Mistakes:
  • Confusing with prefix/suffix approach O(n)
  • Assuming sorting or log factor involved
  • Mistaking inner loops as constant time
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