47~541连接更新‘
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
# 84.柱状图中最大的矩形
|
||||
|
||||
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
|
||||
[力扣题目链接](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/)
|
||||
|
||||
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
# 思路
|
||||
|
||||
本题和[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw),是遥相呼应的两道题目,建议都要仔细做一做,原理上有很多相同的地方,但细节上又有差异,更可以加深对单调栈的理解!
|
||||
本题和[42. 接雨水](https://programmercarl.com/0042.接雨水.html),是遥相呼应的两道题目,建议都要仔细做一做,原理上有很多相同的地方,但细节上又有差异,更可以加深对单调栈的理解!
|
||||
|
||||
其实这两道题目先做那一道都可以,但我先写的42.接雨水的题解,所以如果没做过接雨水的话,建议先做一做接雨水,可以参考我的题解:[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)
|
||||
其实这两道题目先做那一道都可以,但我先写的42.接雨水的题解,所以如果没做过接雨水的话,建议先做一做接雨水,可以参考我的题解:[42. 接雨水](https://programmercarl.com/0042.接雨水.html)
|
||||
|
||||
我们先来看一下双指针的解法:
|
||||
|
||||
@@ -50,11 +50,11 @@ public:
|
||||
|
||||
## 动态规划
|
||||
|
||||
本题动态规划的写法整体思路和[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)是一致的,但要比[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)难一些。
|
||||
本题动态规划的写法整体思路和[42. 接雨水](https://programmercarl.com/0042.接雨水.html)是一致的,但要比[42. 接雨水](https://programmercarl.com/0042.接雨水.html)难一些。
|
||||
|
||||
难就难在本题要记录记录每个柱子 左边第一个小于该柱子的下标,而不是左边第一个小于该柱子的高度。
|
||||
|
||||
所以需要循环查找,也就是下面在寻找的过程中使用了while,详细请看下面注释,整理思路在题解:[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)中已经介绍了。
|
||||
所以需要循环查找,也就是下面在寻找的过程中使用了while,详细请看下面注释,整理思路在题解:[42. 接雨水](https://programmercarl.com/0042.接雨水.html)中已经介绍了。
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
@@ -95,11 +95,11 @@ public:
|
||||
|
||||
本地单调栈的解法和接雨水的题目是遥相呼应的。
|
||||
|
||||
为什么这么说呢,[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。
|
||||
为什么这么说呢,[42. 接雨水](https://programmercarl.com/0042.接雨水.html)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。
|
||||
|
||||
**这里就涉及到了单调栈很重要的性质,就是单调栈里的顺序,是从小到大还是从大到小**。
|
||||
|
||||
在题解[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)中我讲解了接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
|
||||
在题解[42. 接雨水](https://programmercarl.com/0042.接雨水.html)中我讲解了接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
|
||||
|
||||
那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
|
||||
理解这一点,对单调栈就掌握的比较到位了。
|
||||
|
||||
除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。
|
||||
除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解[42. 接雨水](https://programmercarl.com/0042.接雨水.html)我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。
|
||||
|
||||
剩下就是分析清楚如下三种情况:
|
||||
|
||||
@@ -195,40 +195,6 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
动态规划
|
||||
```java
|
||||
class Solution {
|
||||
public int largestRectangleArea(int[] heights) {
|
||||
int length = heights.length;
|
||||
int[] minLeftIndex = new int [length];
|
||||
int[] maxRigthIndex = new int [length];
|
||||
|
||||
// 记录左边第一个小于该柱子的下标
|
||||
minLeftIndex[0] = -1 ;
|
||||
for (int i = 1; i < length; i++) {
|
||||
int t = i - 1;
|
||||
// 这里不是用if,而是不断向右寻找的过程
|
||||
while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];
|
||||
minLeftIndex[i] = t;
|
||||
}
|
||||
// 记录每个柱子 右边第一个小于该柱子的下标
|
||||
maxRigthIndex[length - 1] = length;
|
||||
for (int i = length - 2; i >= 0; i--) {
|
||||
int t = i + 1;
|
||||
while(t < length && heights[t] >= heights[i]) t = maxRigthIndex[t];
|
||||
maxRigthIndex[i] = t;
|
||||
}
|
||||
// 求和
|
||||
int result = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1);
|
||||
result = Math.max(sum, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
动态规划
|
||||
|
||||
Reference in New Issue
Block a user