[LeetCode] 85. Maximal Rectangle(最大矩阵)
- Difficulty: Hard
- Related Topics: Array, Hash Table, Dynamic Programming, Stack
- Link: https://leetcode.com/problems/maximal-rectangle/
Description
Given a rows x cols
binary matrix
filled with 0
's and 1
's, find the largest rectangle containing only 1
's and return its area.
给定一 row x cols
的二进制矩阵 matrix
,矩阵每个元素都是 0
或 1
,找到只包含 1
的最大子矩阵并返回它的面积。
Examples
Example 1
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.
Example 2
Input: matrix = []
Output: 0
Example 3
Input: matrix = [["0"]]
Output: 0
Example 4
Input: matrix = [["1"]]
Output: 1
Example 5
Input: matrix = [["0","0"]]
Output: 0
Constraints
rows == matrix.length
cols == matrix.length
0 <= row, cols <= 200
matrix[i][j]
is'0'
or'1'
.
Solution
这题的做法与第 84 题一致,甚至可以直接套用代码。以 Example 1 为例,想象把横坐标轴放在矩阵的第一行下方,每一列从坐标轴开始连续的 1 看作『柱子』,问题直接转换成 84 题,我们只要不断下移坐标轴,更新面积的最大值即可。对于 Example 1 的矩阵,每一行对应的 height
分别为:
[1, 0, 1, 0, 0]
[2, 0, 2, 1, 1]
[3, 1, 3, 2, 2]
[4, 0, 0, 3, 0]
代码如下:
import kotlin.math.max
class Solution {
fun maximalRectangle(matrix: Array<CharArray>): Int {
if (matrix.isEmpty() || matrix[0].isEmpty()) {
return 0
}
val colLen = matrix[0].size
val heights = IntArray(colLen)
var result = 0
for (row in matrix) {
for (i in row.indices) {
if (row[i] == '1') {
heights[i]++
} else {
heights[i] = 0
}
}
result = max(result, largestRectangleArea(heights))
}
return result
}
private fun largestRectangleArea(heights: IntArray): Int {
if (heights.isEmpty()) {
return 0
}
val lessFromLeft = IntArray(heights.size)
val lessFromRight = IntArray(heights.size)
lessFromLeft[0] = -1
lessFromRight[lessFromRight.lastIndex] = heights.size
for (i in 1..heights.lastIndex) {
var p = i - 1
while (p >= 0 && heights[p] >= heights[i]) {
p = lessFromLeft[p]
}
lessFromLeft[i] = p
}
for (i in (heights.lastIndex - 1) downTo 0) {
var p = i + 1
while (p < heights.size && heights[p] >= heights[i]) {
p = lessFromRight[p]
}
lessFromRight[i] = p
}
var result = 0
for (i in heights.indices) {
result = max(result, heights[i] * (lessFromRight[i] - lessFromLeft[i] - 1))
}
return result
}
}