LeetCode 85. 最大矩形

核心思路
这道题的难点在于如何高效地处理二维矩阵中的矩形面积计算。我们可以将问题拆解为多个一维直方图的最大矩形问题。
具体做法是遍历矩阵的每一行,维护一个高度数组 heights。如果当前格子是 '1',则对应位置的高度累加;如果是 '0',则重置为 0。这样每一行都变成了一个直方图,我们只需要对每个直方图求最大矩形面积,并取所有行中的最大值即可。
对于单个直方图的最大矩形求解,单调栈是最优解法。我们需要确定每个柱子作为高时,左右两边能延伸的最远边界。
确定右边界
当我们遍历到索引 i,高度为 h 时,如果 h 小于或等于栈顶元素对应的高度,说明栈顶那个柱子右边第一次遇到更矮的柱子就是当前位置 i。此时我们可以立刻确定栈顶元素的右边界 right[top] = i,并将其弹出。重复此过程直到栈顶高度小于 h,从而保持栈内高度的递增性。
这意味着,所有柱子的右边界都是在它们'出栈'的那一刻被确定的。
确定左边界
当弹栈操作结束后,如果栈不为空,新的栈顶元素就是左边离 i 最近且比当前高度矮的柱子下标,即 left[i] = stk[top]。如果栈为空,说明左边没有更矮的柱子,左边界记为 -1。
左边界是在元素'入栈前'通过查看当前栈顶直接得到的。
Go 语言实现
func maximalRectangle(matrix [][]byte) int {
n := len(matrix[0])
heights := make([]int, n)
ans := 0
for _, row := range matrix {
for j, c := range row {
if c == '1' {
heights[j]++
} else {
heights[j] = 0
}
}
ans = max(ans, largeArea(heights))
}
return ans
}
func largeArea(height []int) int {
n := (height)
stk := ([], )
left, right := ([], n), ([], n)
i := n {
right[i] = n
}
i, h := height {
(stk) > && height[stk[(stk)]] >= h {
right[stk[(stk)]] = i
stk = stk[:(stk)]
}
(stk) > {
left[i] = stk[(stk)]
} {
left[i] =
}
stk = (stk, i)
}
res :=
i := n {
res = max(res, height[i]*(right[i]-left[i]))
}
res
}



