Skip to content

Commit 7fceb0d

Browse files
author
binbin.hou
committed
[Feature] add for new
1 parent 0449e2e commit 7fceb0d

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
title: LC84. 柱状图中最大的矩形 largest-rectangle-in-histogram
3+
date: 2025-10-21
4+
categories: [TopInterview150]
5+
tags: [leetcode, topInterview150, array, sort]
6+
published: true
7+
---
8+
9+
# LC84. 柱状图中最大的矩形 largest-rectangle-in-histogram
10+
11+
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
12+
13+
求在该柱状图中,能够勾勒出来的矩形的最大面积。
14+
15+
示例 1:
16+
17+
![1](https://assets.leetcode.com/uploads/2021/01/04/histogram.jpg)
18+
19+
输入:heights = [2,1,5,6,2,3]
20+
输出:10
21+
解释:最大的矩形为图中红色区域,面积为 10
22+
23+
24+
示例 2:
25+
26+
![2](https://assets.leetcode.com/uploads/2021/01/04/histogram-1.jpg)
27+
28+
输入: heights = [2,4]
29+
输出: 4
30+
31+
32+
提示:
33+
34+
1 <= heights.length <=10^5
35+
36+
0 <= heights[i] <= 10^4
37+
38+
# v1-左右扫描
39+
40+
## 思路
41+
42+
对每个柱子 i:
43+
44+
向左扫描找到第一个比它矮的柱子 → left[i]
45+
46+
向右扫描找到第一个比它矮的柱子 → right[i]
47+
48+
面积 = `heights[i] * (right[i] - left[i] - 1)`
49+
50+
注意这里边界的计算方式稍微不同,因为 left[i] 和 right[i] 是“第一个比自己矮的柱子”的索引,所以是不包含二者的。
51+
52+
这里宽度如果要简单推断的话:
53+
54+
```
55+
width = 最右索引 - 最左索引 + 1
56+
= (right[i]-1) - (left[i]+1) + 1
57+
= right[i] - left[i] - 1
58+
```
59+
60+
## 实现
61+
62+
```java
63+
class Solution {
64+
public int largestRectangleArea(int[] heights) {
65+
int n = heights.length;
66+
67+
// 看左边
68+
int[] left = new int[n];
69+
for(int i = 0; i < n; i++) {
70+
int j = i-1;
71+
while(j >= 0 && heights[j] >= heights[i]) {
72+
j--;
73+
}
74+
left[i] = j;
75+
}
76+
77+
// 看右边
78+
int[] right = new int[n];
79+
for(int i = 0; i < n; i++) {
80+
int j = i+1;
81+
while(j < n && heights[j] >= heights[i]) {
82+
j++;
83+
}
84+
right[i]= j;
85+
}
86+
87+
// 看结果
88+
int max = 0;
89+
for(int i = 0; i < n; i++) {
90+
int area = (right[i] - left[i] - 1) * heights[i];
91+
max = Math.max(area, max);
92+
}
93+
return max;
94+
}
95+
}
96+
```
97+
98+
## 效果
99+
100+
超出时间限制
101+
93 / 99 个通过的测试用例
102+
103+
## 复杂度
104+
105+
TC: O(n^2)
106+
107+
## 反思
108+
109+
如果「左边的状态」会影响当前,但「右边的状态」也可能有另一种独立影响,那就很可能要分别从两个方向处理。
110+
111+
但是这里超时了,我们要想办法提升一下效率。
112+
113+
# v2-单调栈
114+
115+
## 思路
116+
117+
在对比左右的时候,每次都从头开始遍历,导致最差的时候复杂度为 O(n^2)。数据量比较大的时候直接超时。
118+
119+
120+
121+
122+
123+
124+
125+
126+
127+
## 小结
128+
129+
类似的题目其实还是不少的。
130+
131+
| 题目 | 为什么双向扫描 |
132+
| --------------------------------------- | ------------------ |
133+
| **LC135 Candy** | 要同时满足左、右的“评分高→糖果多” |
134+
| **LC42 Trapping Rain Water** | 每格水高度由左右最高墙共同决定 |
135+
| **LC84 Largest Rectangle in Histogram** | 每个柱子的最大宽度取决于左右边界 |
136+
| **LC739 Daily Temperatures** | 每天温度要看右边第一个更高温度的位置 |
137+
| **LC238 Product of Array Except Self** | 每个位置要看左积和右积 |
138+
139+
140+
141+
142+
143+
# 开源地址
144+
145+
为了便于大家学习,所有实现均已开源。欢迎 fork + star~
146+
147+
> 笔记 [https://github.com/houbb/leetcode-notes](https://github.com/houbb/leetcode-notes)
148+
149+
> 源码 [https://github.com/houbb/leetcode](https://github.com/houbb/leetcode)
150+
151+
152+
# 参考资料
153+
154+
https://leetcode.cn/problems/jump-game-ix/solutions/3762167/jie-lun-ti-pythonjavacgo-by-endlesscheng-x2qu/

0 commit comments

Comments
 (0)