| Problem Signal | Technique |
|---|---|
| Find largest rectangle in binary matrix | Histogram + monotonic stack (LC 85) |
| Count all rectangles in binary matrix | Histogram + monotonic stack (LC 1504) |
| Largest submatrix with column rearrangements | Histogram + sort each row (LC 1727) |
| Matrix has "continuous 1s" constraint per column | Histogram model reduces 2D to 1D per row |
The histogram model compresses a 2D binary matrix into a 1D histogram for each row. Each histogram bar represents the number of continuous 1s ending at that row in that column. Once you have a histogram per row, you reduce matrix problems to histogram problems (usually LC 84 variants).
Key insight: For each row, treat it as the base of a histogram and solve "largest rectangle in histogram" (or counting/variant problems) on that 1D array.
hist = [0] * len(A[0])
for i in range(len(A)):
for j in range(len(A[0])):
if A[i][j]:
hist[j] += 1
else:
hist[j] = 0
# now hist[j] = number of consecutive 1s ending at row i, column j
# solve 1D histogram problem on histNot included in this directory, but the histogram model reduces matrix problems to this. Given a histogram, find the largest rectangle area.
Solution: Use monotonic stack to find the next smaller element on left and right for each bar. For each bar as height, the width is right - left - 1.
def largestRectangleArea(heights):
n = len(heights)
# next smaller on the right
R = [n] * n
stk = []
for i in range(n):
while stk and heights[stk[-1]] > heights[i]:
R[stk.pop()] = i
stk.append(i)
# next smaller on the left
L = [-1] * n
stk = []
for i in reversed(range(n)):
while stk and heights[stk[-1]] >= heights[i]:
L[stk.pop()] = i
stk.append(i)
# for each heights[i] as minimum height, find max rectangle
ans = 0
for i in range(n):
ans = max(ans, heights[i] * (R[i] - L[i] - 1))
return ansBuild histogram for each row, solve LC 84 on each histogram.
def maximalRectangle(matrix):
if not matrix: return 0
ans = 0
hist = [0] * len(matrix[0])
for row in matrix:
for j in range(len(row)):
if row[j] == "1":
hist[j] += 1
else:
hist[j] = 0
ans = max(ans, largestRectangleArea(hist))
return ansBuild histogram for each row, but we can rearrange columns. So sort the histogram in descending order and compute max area.
def largestSubmatrix(matrix):
ans = 0
hist = [0] * len(matrix[0])
for row in matrix:
for j in range(len(matrix[0])):
if row[j]:
hist[j] += 1
else:
hist[j] = 0
# can rearrange columns, so sort descending
sorted_hist = sorted(hist, reverse=True)
for k, height in enumerate(sorted_hist):
ans = max(ans, height * (k + 1))
return ansBuild histogram for each row. For each histogram, count all rectangles bottom-right at each position using monotonic stack. This is a harder variant of LC 84.
Key insight: For position j, count how many rectangles end at j. Use a monotonic non-decreasing stack. When popping, adjust the count to reflect the lower height.
def numSubmat(matrix):
m, n = len(matrix), len(matrix[0])
# build histogram in-place
for i in range(m):
for j in range(n):
if matrix[i][j] and i > 0:
matrix[i][j] += matrix[i - 1][j]
ans = 0
for i in range(m):
stack = [] # mono-stack of non-decreasing height
cnt = 0
for j in range(n):
# pop taller bars
while stack and matrix[i][stack[-1]] > matrix[i][j]:
jj = stack.pop()
kk = stack[-1] if stack else -1
# adjust count to reflect lower height
cnt -= (matrix[i][jj] - matrix[i][j]) * (jj - kk)
# add rectangles ending at j with height matrix[i][j]
cnt += matrix[i][j]
ans += cnt
stack.append(j)
return ansMaximal square is usually solved with DP, not histogram model. But you can also solve it with histogram + sliding window to enforce width = height.
DP approach (simpler):
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1| Problem | Difficulty | Key Insight |
|---|---|---|
| LC 84: Largest Rectangle in Histogram | L2 | Monotonic stack to find next smaller left/right |
| LC 85: Maximal Rectangle | L3 | Histogram + LC 84 for each row |
| LC 1504: Count Submatrices With All Ones | L3 | Histogram + monotonic stack counting variant |
| LC 1727: Largest Submatrix with Rearrangements | L1 | Histogram + sort each row |
| LC 221: Maximal Square | L1 | DP (not histogram-based, but related) |
- Histogram model converts 2D matrix problems into a series of 1D histogram problems.
- For "maximum" problems, usually pair with monotonic stack (LC 84 pattern).
- For "count all" problems, use monotonic stack with careful counting logic (LC 1504).
- If you can rearrange columns, sort the histogram (LC 1727).
- The histogram template is the same for all problems. The difference is what you do with each histogram.
- Build histogram row-by-row (iterate top to bottom), not column-by-column.