Skip to content

Commit a6b0106

Browse files
committed
feat: add solutions to lc problems: No.0084,0085
* No.0084.Largest Rectangle in Histogram/ * No.0085.Maximal Rectangle
1 parent a430d33 commit a6b0106

File tree

9 files changed

+538
-36
lines changed

9 files changed

+538
-36
lines changed

solution/0000-0099/0084.Largest Rectangle in Histogram/README.md

+29-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46-
单调栈
46+
**方法一:单调栈**
4747

4848
单调栈常见模型:找出每个数左/右边**离它最近的****比它大/小的数**。模板:
4949

@@ -55,7 +55,9 @@ for i in range(n):
5555
stk.append(i)
5656
```
5757

58-
枚举每根柱子的高度 h 作为矩形的高度,向左右两边找第一个高度小于 h 的下标 `left[i]`, `right[i]`。那么此时矩形面积为 `h * (right[i] - left[i] - 1)`,求最大值即可。
58+
枚举每根柱子的高度 $h$ 作为矩形的高度,向左右两边找第一个高度小于 $h$ 的下标 $left_i$, $right_i$。那么此时矩形面积为 $h \times (right_i-left_i-1)$,求最大值即可。
59+
60+
时间复杂度 $O(n)$,其中 $n$ 表示 $heights$ 的长度。
5961

6062
<!-- tabs:start -->
6163

@@ -66,7 +68,7 @@ for i in range(n):
6668
```python
6769
class Solution:
6870
def largestRectangleArea(self, heights: List[int]) -> int:
69-
res, n = 0, len(heights)
71+
n = len(heights)
7072
stk = []
7173
left = [-1] * n
7274
right = [n] * n
@@ -77,9 +79,31 @@ class Solution:
7779
if stk:
7880
left[i] = stk[-1]
7981
stk.append(i)
82+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))
83+
```
84+
85+
```python
86+
class Solution:
87+
def largestRectangleArea(self, heights: List[int]) -> int:
88+
n = len(heights)
89+
stk = []
90+
left = [-1] * n
91+
right = [n] * n
8092
for i, h in enumerate(heights):
81-
res = max(res, h * (right[i] - left[i] - 1))
82-
return res
93+
while stk and heights[stk[-1]] >= h:
94+
stk.pop()
95+
if stk:
96+
left[i] = stk[-1]
97+
stk.append(i)
98+
stk = []
99+
for i in range(n - 1, -1, -1):
100+
h = heights[i]
101+
while stk and heights[stk[-1]] >= h:
102+
stk.pop()
103+
if stk:
104+
right[i] = stk[-1]
105+
stk.append(i)
106+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))
83107
```
84108

85109
### **Java**

solution/0000-0099/0084.Largest Rectangle in Histogram/README_EN.md

+25-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The largest rectangle is shown in the red area, which has an area = 10 units.
4040
```python
4141
class Solution:
4242
def largestRectangleArea(self, heights: List[int]) -> int:
43-
res, n = 0, len(heights)
43+
n = len(heights)
4444
stk = []
4545
left = [-1] * n
4646
right = [n] * n
@@ -51,9 +51,31 @@ class Solution:
5151
if stk:
5252
left[i] = stk[-1]
5353
stk.append(i)
54+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))
55+
```
56+
57+
```python
58+
class Solution:
59+
def largestRectangleArea(self, heights: List[int]) -> int:
60+
n = len(heights)
61+
stk = []
62+
left = [-1] * n
63+
right = [n] * n
5464
for i, h in enumerate(heights):
55-
res = max(res, h * (right[i] - left[i] - 1))
56-
return res
65+
while stk and heights[stk[-1]] >= h:
66+
stk.pop()
67+
if stk:
68+
left[i] = stk[-1]
69+
stk.append(i)
70+
stk = []
71+
for i in range(n - 1, -1, -1):
72+
h = heights[i]
73+
while stk and heights[stk[-1]] >= h:
74+
stk.pop()
75+
if stk:
76+
right[i] = stk[-1]
77+
stk.append(i)
78+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))
5779
```
5880

5981
### **Java**
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Solution:
22
def largestRectangleArea(self, heights: List[int]) -> int:
3-
res, n = 0, len(heights)
3+
n = len(heights)
44
stk = []
55
left = [-1] * n
66
right = [n] * n
@@ -11,6 +11,4 @@ def largestRectangleArea(self, heights: List[int]) -> int:
1111
if stk:
1212
left[i] = stk[-1]
1313
stk.append(i)
14-
for i, h in enumerate(heights):
15-
res = max(res, h * (right[i] - left[i] - 1))
16-
return res
14+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))

solution/0000-0099/0085.Maximal Rectangle/README.md

+171-1
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,192 @@
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64+
**方法一:单调栈**
65+
66+
把每一行视为柱状图的底部,对每一行求柱状图的最大面积即可。
67+
68+
时间复杂度 $O(mn)$,其中 $m$ 表示 $matrix$ 的行数,$n$ 表示 $matrix$ 的列数。
69+
6470
<!-- tabs:start -->
6571

6672
### **Python3**
6773

6874
<!-- 这里可写当前语言的特殊实现逻辑 -->
6975

7076
```python
71-
77+
class Solution:
78+
def maximalRectangle(self, matrix: List[List[str]]) -> int:
79+
heights = [0] * len(matrix[0])
80+
ans = 0
81+
for row in matrix:
82+
for j, v in enumerate(row):
83+
if v == "1":
84+
heights[j] += 1
85+
else:
86+
heights[j] = 0
87+
ans = max(ans, self.largestRectangleArea(heights))
88+
return ans
89+
90+
def largestRectangleArea(self, heights: List[int]) -> int:
91+
n = len(heights)
92+
stk = []
93+
left = [-1] * n
94+
right = [n] * n
95+
for i, h in enumerate(heights):
96+
while stk and heights[stk[-1]] >= h:
97+
stk.pop()
98+
if stk:
99+
left[i] = stk[-1]
100+
stk.append(i)
101+
stk = []
102+
for i in range(n - 1, -1, -1):
103+
h = heights[i]
104+
while stk and heights[stk[-1]] >= h:
105+
stk.pop()
106+
if stk:
107+
right[i] = stk[-1]
108+
stk.append(i)
109+
return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))
72110
```
73111

74112
### **Java**
75113

76114
<!-- 这里可写当前语言的特殊实现逻辑 -->
77115

78116
```java
117+
class Solution {
118+
public int maximalRectangle(char[][] matrix) {
119+
int n = matrix[0].length;
120+
int[] heights = new int[n];
121+
int ans = 0;
122+
for (var row : matrix) {
123+
for (int j = 0; j < n; ++j) {
124+
if (row[j] == '1') {
125+
heights[j] += 1;
126+
} else {
127+
heights[j] = 0;
128+
}
129+
}
130+
ans = Math.max(ans, largestRectangleArea(heights));
131+
}
132+
return ans;
133+
}
134+
135+
private int largestRectangleArea(int[] heights) {
136+
int res = 0, n = heights.length;
137+
Deque<Integer> stk = new ArrayDeque<>();
138+
int[] left = new int[n];
139+
int[] right = new int[n];
140+
Arrays.fill(right, n);
141+
for (int i = 0; i < n; ++i) {
142+
while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) {
143+
right[stk.pop()] = i;
144+
}
145+
left[i] = stk.isEmpty() ? -1 : stk.peek();
146+
stk.push(i);
147+
}
148+
for (int i = 0; i < n; ++i) {
149+
res = Math.max(res, heights[i] * (right[i] - left[i] - 1));
150+
}
151+
return res;
152+
}
153+
}
154+
```
155+
156+
### **C++**
157+
158+
```cpp
159+
class Solution {
160+
public:
161+
int maximalRectangle(vector<vector<char>>& matrix) {
162+
int n = matrix[0].size();
163+
vector<int> heights(n);
164+
int ans = 0;
165+
for (auto& row : matrix)
166+
{
167+
for (int j = 0; j < n; ++j)
168+
{
169+
if (row[j] == '1') ++heights[j];
170+
else heights[j] = 0;
171+
}
172+
ans = max(ans, largestRectangleArea(heights));
173+
}
174+
return ans;
175+
}
176+
177+
int largestRectangleArea(vector<int>& heights) {
178+
int res = 0, n = heights.size();
179+
stack<int> stk;
180+
vector<int> left(n, -1);
181+
vector<int> right(n, n);
182+
for (int i = 0; i < n; ++i)
183+
{
184+
while (!stk.empty() && heights[stk.top()] >= heights[i])
185+
{
186+
right[stk.top()] = i;
187+
stk.pop();
188+
}
189+
if (!stk.empty()) left[i] = stk.top();
190+
stk.push(i);
191+
}
192+
for (int i = 0; i < n; ++i)
193+
res = max(res, heights[i] * (right[i] - left[i] - 1));
194+
return res;
195+
}
196+
};
197+
```
79198

199+
### **Go**
200+
201+
```go
202+
func maximalRectangle(matrix [][]byte) int {
203+
n := len(matrix[0])
204+
heights := make([]int, n)
205+
ans := 0
206+
for _, row := range matrix {
207+
for j, v := range row {
208+
if v == '1' {
209+
heights[j]++
210+
} else {
211+
heights[j] = 0
212+
}
213+
}
214+
ans = max(ans, largestRectangleArea(heights))
215+
}
216+
return ans
217+
}
218+
219+
func largestRectangleArea(heights []int) int {
220+
res, n := 0, len(heights)
221+
var stk []int
222+
left, right := make([]int, n), make([]int, n)
223+
for i := range right {
224+
right[i] = n
225+
}
226+
for i, h := range heights {
227+
for len(stk) > 0 && heights[stk[len(stk)-1]] >= h {
228+
right[stk[len(stk)-1]] = i
229+
stk = stk[:len(stk)-1]
230+
}
231+
if len(stk) > 0 {
232+
left[i] = stk[len(stk)-1]
233+
} else {
234+
left[i] = -1
235+
}
236+
stk = append(stk, i)
237+
}
238+
for i, h := range heights {
239+
res = max(res, h*(right[i]-left[i]-1))
240+
}
241+
return res
242+
}
243+
244+
func max(a, b int) int {
245+
if a > b {
246+
return a
247+
}
248+
return b
249+
}
80250
```
81251

82252
### **...**

0 commit comments

Comments
 (0)