|
69 | 69 |
|
70 | 70 | **方法一:单调栈**
|
71 | 71 |
|
72 |
| -- 首先在柱状图中求最大矩形面积可以通过单调栈,维护每一列的左边第一个比它小的位置 $L$,和右边第一个比它小的位置 $R$,就能得到以这一列为高的最大矩形面积为 $(R-L-1)*h$。 |
73 |
| -- 考虑每一行作为底边的柱状图中,能够得到的最大的矩形面积。再对每一行的最大面积取 $max$ 就是最终的答案。 |
74 |
| -- 柱状图中每一列的高可以通过类似前缀和的方式去维护。 |
75 |
| -- 假设矩阵大小为 $n*m$,那么时间复杂为 $O(nm)$,空间复杂度为 $O(m)$。 |
| 72 | +把每一行视为柱状图的底部,对每一行求柱状图的最大面积即可。 |
| 73 | + |
| 74 | +时间复杂度 $O(mn)$,其中 $m$ 表示 $matrix$ 的行数,$n$ 表示 $matrix$ 的列数。 |
76 | 75 |
|
77 | 76 | <!-- tabs:start -->
|
78 | 77 |
|
|
81 | 80 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
82 | 81 |
|
83 | 82 | ```python
|
84 |
| - |
| 83 | +class Solution: |
| 84 | + def maximalRectangle(self, matrix: List[List[str]]) -> int: |
| 85 | + if not matrix: |
| 86 | + return 0 |
| 87 | + heights = [0] * len(matrix[0]) |
| 88 | + ans = 0 |
| 89 | + for row in matrix: |
| 90 | + for j, v in enumerate(row): |
| 91 | + if v == "1": |
| 92 | + heights[j] += 1 |
| 93 | + else: |
| 94 | + heights[j] = 0 |
| 95 | + ans = max(ans, self.largestRectangleArea(heights)) |
| 96 | + return ans |
| 97 | + |
| 98 | + def largestRectangleArea(self, heights: List[int]) -> int: |
| 99 | + n = len(heights) |
| 100 | + stk = [] |
| 101 | + left = [-1] * n |
| 102 | + right = [n] * n |
| 103 | + for i, h in enumerate(heights): |
| 104 | + while stk and heights[stk[-1]] >= h: |
| 105 | + stk.pop() |
| 106 | + if stk: |
| 107 | + left[i] = stk[-1] |
| 108 | + stk.append(i) |
| 109 | + stk = [] |
| 110 | + for i in range(n - 1, -1, -1): |
| 111 | + h = heights[i] |
| 112 | + while stk and heights[stk[-1]] >= h: |
| 113 | + stk.pop() |
| 114 | + if stk: |
| 115 | + right[i] = stk[-1] |
| 116 | + stk.append(i) |
| 117 | + return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights)) |
85 | 118 | ```
|
86 | 119 |
|
87 | 120 | ### **Java**
|
88 | 121 |
|
89 | 122 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
90 | 123 |
|
91 | 124 | ```java
|
| 125 | +class Solution { |
| 126 | + public int maximalRectangle(String[] matrix) { |
| 127 | + if (matrix == null || matrix.length == 0) { |
| 128 | + return 0; |
| 129 | + } |
| 130 | + int n = matrix[0].length(); |
| 131 | + int[] heights = new int[n]; |
| 132 | + int ans = 0; |
| 133 | + for (var row : matrix) { |
| 134 | + for (int j = 0; j < n; ++j) { |
| 135 | + if (row.charAt(j) == '1') { |
| 136 | + heights[j] += 1; |
| 137 | + } else { |
| 138 | + heights[j] = 0; |
| 139 | + } |
| 140 | + } |
| 141 | + ans = Math.max(ans, largestRectangleArea(heights)); |
| 142 | + } |
| 143 | + return ans; |
| 144 | + } |
92 | 145 |
|
| 146 | + private int largestRectangleArea(int[] heights) { |
| 147 | + int res = 0, n = heights.length; |
| 148 | + Deque<Integer> stk = new ArrayDeque<>(); |
| 149 | + int[] left = new int[n]; |
| 150 | + int[] right = new int[n]; |
| 151 | + Arrays.fill(right, n); |
| 152 | + for (int i = 0; i < n; ++i) { |
| 153 | + while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { |
| 154 | + right[stk.pop()] = i; |
| 155 | + } |
| 156 | + left[i] = stk.isEmpty() ? -1 : stk.peek(); |
| 157 | + stk.push(i); |
| 158 | + } |
| 159 | + for (int i = 0; i < n; ++i) { |
| 160 | + res = Math.max(res, heights[i] * (right[i] - left[i] - 1)); |
| 161 | + } |
| 162 | + return res; |
| 163 | + } |
| 164 | +} |
93 | 165 | ```
|
94 | 166 |
|
95 | 167 | ### **C++**
|
96 | 168 |
|
| 169 | +- 首先在柱状图中求最大矩形面积可以通过单调栈,维护每一列的左边第一个比它小的位置 $L$,和右边第一个比它小的位置 $R$,就能得到以这一列为高的最大矩形面积为 $(R-L-1)*h$。 |
| 170 | +- 考虑每一行作为底边的柱状图中,能够得到的最大的矩形面积。再对每一行的最大面积取 $max$ 就是最终的答案。 |
| 171 | +- 柱状图中每一列的高可以通过类似前缀和的方式去维护。 |
| 172 | +- 假设矩阵大小为 $n*m$,那么时间复杂为 $O(nm)$,空间复杂度为 $O(m)$。 |
| 173 | + |
97 | 174 | ```cpp
|
98 | 175 | class Solution {
|
99 | 176 | public:
|
@@ -130,6 +207,104 @@ public:
|
130 | 207 | };
|
131 | 208 | ```
|
132 | 209 |
|
| 210 | +```cpp |
| 211 | +class Solution { |
| 212 | +public: |
| 213 | + int maximalRectangle(vector<string>& matrix) { |
| 214 | + if (matrix.empty()) return 0; |
| 215 | + int n = matrix[0].size(); |
| 216 | + vector<int> heights(n); |
| 217 | + int ans = 0; |
| 218 | + for (auto& row : matrix) |
| 219 | + { |
| 220 | + for (int j = 0; j < n; ++j) |
| 221 | + { |
| 222 | + if (row[j] == '1') ++heights[j]; |
| 223 | + else heights[j] = 0; |
| 224 | + } |
| 225 | + ans = max(ans, largestRectangleArea(heights)); |
| 226 | + } |
| 227 | + return ans; |
| 228 | + } |
| 229 | +
|
| 230 | + int largestRectangleArea(vector<int>& heights) { |
| 231 | + int res = 0, n = heights.size(); |
| 232 | + stack<int> stk; |
| 233 | + vector<int> left(n, -1); |
| 234 | + vector<int> right(n, n); |
| 235 | + for (int i = 0; i < n; ++i) |
| 236 | + { |
| 237 | + while (!stk.empty() && heights[stk.top()] >= heights[i]) |
| 238 | + { |
| 239 | + right[stk.top()] = i; |
| 240 | + stk.pop(); |
| 241 | + } |
| 242 | + if (!stk.empty()) left[i] = stk.top(); |
| 243 | + stk.push(i); |
| 244 | + } |
| 245 | + for (int i = 0; i < n; ++i) |
| 246 | + res = max(res, heights[i] * (right[i] - left[i] - 1)); |
| 247 | + return res; |
| 248 | + } |
| 249 | +}; |
| 250 | +``` |
| 251 | + |
| 252 | +### **Go** |
| 253 | + |
| 254 | +```go |
| 255 | +func maximalRectangle(matrix []string) int { |
| 256 | + if len(matrix) == 0 { |
| 257 | + return 0 |
| 258 | + } |
| 259 | + n := len(matrix[0]) |
| 260 | + heights := make([]int, n) |
| 261 | + ans := 0 |
| 262 | + for _, row := range matrix { |
| 263 | + for j, v := range row { |
| 264 | + if v == '1' { |
| 265 | + heights[j]++ |
| 266 | + } else { |
| 267 | + heights[j] = 0 |
| 268 | + } |
| 269 | + } |
| 270 | + ans = max(ans, largestRectangleArea(heights)) |
| 271 | + } |
| 272 | + return ans |
| 273 | +} |
| 274 | + |
| 275 | +func largestRectangleArea(heights []int) int { |
| 276 | + res, n := 0, len(heights) |
| 277 | + var stk []int |
| 278 | + left, right := make([]int, n), make([]int, n) |
| 279 | + for i := range right { |
| 280 | + right[i] = n |
| 281 | + } |
| 282 | + for i, h := range heights { |
| 283 | + for len(stk) > 0 && heights[stk[len(stk)-1]] >= h { |
| 284 | + right[stk[len(stk)-1]] = i |
| 285 | + stk = stk[:len(stk)-1] |
| 286 | + } |
| 287 | + if len(stk) > 0 { |
| 288 | + left[i] = stk[len(stk)-1] |
| 289 | + } else { |
| 290 | + left[i] = -1 |
| 291 | + } |
| 292 | + stk = append(stk, i) |
| 293 | + } |
| 294 | + for i, h := range heights { |
| 295 | + res = max(res, h*(right[i]-left[i]-1)) |
| 296 | + } |
| 297 | + return res |
| 298 | +} |
| 299 | + |
| 300 | +func max(a, b int) int { |
| 301 | + if a > b { |
| 302 | + return a |
| 303 | + } |
| 304 | + return b |
| 305 | +} |
| 306 | +``` |
| 307 | + |
133 | 308 | ### **...**
|
134 | 309 |
|
135 | 310 | ```
|
|
0 commit comments