Skip to content

Commit 834f9d8

Browse files
committed
Merge branch 'master' of github.com:JalanJiang/leetcode-notebook
2 parents 638ac51 + 8a1da87 commit 834f9d8

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

Diff for: docs/data-structure/stack/README.md

+90
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,96 @@ class Solution(object):
4747
return True
4848
```
4949

50+
## 84. 柱状图中最大的矩形
51+
52+
[原题链接](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/)
53+
54+
### 解法一
55+
56+
- 单调栈
57+
- 逐个遍历
58+
- 结果:超时
59+
60+
```python
61+
class Solution:
62+
def largestRectangleArea(self, heights: List[int]) -> int:
63+
stack = [] # 单调递增栈
64+
ans = 0
65+
for h in heights:
66+
stack.append(h)
67+
# if len(stack) == 0:
68+
# stack.append(h)
69+
# else:
70+
# while stack[-1] > h:
71+
# # 对比栈顶元素
72+
# top = stack[-1]
73+
# # 左侧更大的数字被化为小数
74+
# if top > h:
75+
# stack[-1] = h
76+
# stack.append(h)
77+
# print(stack)
78+
# 计算实际面积
79+
stack_length = len(stack)
80+
for i in range(stack_length):
81+
# element = stack[i]
82+
if stack[i] > h:
83+
stack[i] = h
84+
area = (stack_length - i) * stack[i]
85+
ans = max(ans, area)
86+
# print(ans)
87+
88+
return ans
89+
```
90+
91+
### 解法二
92+
93+
面积计算方式:
94+
95+
- 找到 `heights[i]` 左侧第一个小于它的元素位置 `left`
96+
- 找到 `heights[i]` 右侧第一个小于它的元素位置 `right`
97+
- `area = (right - left - 1) * heights[i]`
98+
99+
利用维护单调递增栈得出元素的左右边界:
100+
101+
- 左侧边界(左侧第一个小于当前位置的元素)可以在元素入栈时确认
102+
- 右侧边界(右侧第一个小于当前位置的元素)可以在元素出栈时确认
103+
104+
```python
105+
class Solution:
106+
def largestRectangleArea(self, heights: List[int]) -> int:
107+
# 找左侧第一个小于 h 的位置 left
108+
# 右侧第一个小于 h 的位置 right
109+
# area = (right - left) * h
110+
111+
# 维护单调栈
112+
length = len(heights)
113+
stack = []
114+
lefts = [-1 for _ in range(length)]
115+
rights = [length for _ in range(length)]
116+
for i in range(length):
117+
h = heights[i]
118+
if len(stack) == 0:
119+
stack.append((i, h))
120+
else:
121+
# 维护单调栈
122+
while len(stack) > 0 and stack[-1][1] >= h:
123+
# 弹出时能确认右侧最小元素
124+
min_element = stack.pop()
125+
rights[min_element[0]] = i
126+
# 入栈,确认左侧最小元素
127+
if len(stack) > 0:
128+
lefts[i] = stack[-1][0]
129+
stack.append((i, h))
130+
131+
ans = 0
132+
for i in range(length):
133+
area = (rights[i] - lefts[i] - 1) * heights[i]
134+
# print((rights[i] - lefts[i] + 1))
135+
ans = max(area, ans)
136+
137+
return ans
138+
```
139+
50140
## 150. 逆波兰表达式求值
51141

52142
[原题链接](https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/)

0 commit comments

Comments
 (0)