单调栈总结完毕

This commit is contained in:
estomm
2021-04-13 00:36:09 +08:00
parent ebfe8e0679
commit f6147c41a4
3 changed files with 50 additions and 7 deletions

View File

@@ -69,4 +69,23 @@ for(int i = T.size() - 1; i >= 0; i--){
1. 当前元素出栈的时候,说明当前元素是倒数第二小的元素。
一般会采取怎样的操作呢?具体再总结。
## 问题总结
一般会采取怎样的操作呢?具体再总结。
> * [视野总和](#1-视野总和):利用了**栈内元素的数量计算问题**。
> * [柱形图中的最大矩形](#2-柱状图中的最大矩形):利用的是**出栈序列**。这组序列构成了可能的最大矩形。
> * [接雨水问题](3.3%20接雨水问题.md):单调栈解法也是利用了**出栈序列**。这个序列的左右边界能够形成一个容器。
> * [接雨水问题2](3.3%20接雨水问题.md)
>
> 其它类型的单调栈
> * [求最大区间](#3-求最大区间):利用的**出栈的序列**。表示一个可能的最大值区间。
> * [132模式](#4-132-模式):利用了其**有序性**。
### 总结
综上所述主要有以上三种利用思想。
1. 针对栈内元素数量的利用。第一个问题,仅仅是简单的模拟。
2. 针对有序性的利用。每次都是贪心的求得最大的3反向求解第二大的元素。
3. 针对出栈序列的利用。在递增栈和递减栈中,每一个出栈序列的两端,都是一个最大边界、或者最小边界,在边界中会形成问题的一个解序列。序列中的每个值,比两个边界大或者小。

View File

@@ -31,9 +31,22 @@
* 局部最优:它是当前步骤中所有可行性选择中最佳的局部选择。
* 不可取消:即选择一旦做出,在算法的后面步骤中就无法改变了。
## 2 反向贪心思想
1. 正向贪心思想,每次都能选择最优的结果,最终能够选择所有最优子问题构成的最优解。
2. 反向贪心思想,虽然无法确定当前的最优结果。但是每次都能排除掉最差的结果。通过一系列排除最差结果的方法,得到最后的最优解。
### 实例
* [二维数组的查找](../C类问题类型算法/1.2%20二维数组查找.md)
* [盛最多水的容器](../B类数据结构算法/4.3%20数组与滑动窗口.md)
* [接雨水问题](../B类数据结构算法/3.3%20接雨水问题.md)
以上三个问题,每次的谈心选择,不是选择当前步骤的最优解,而是排除不可能的最差情况。
## 2 常见问题
## 3 常见问题
### 分数背包问题
### 最短路径问题
### Dijkstras Algorithm

View File

@@ -4,11 +4,16 @@
* 柱形图问题多使用单调栈。
> 下边是对柱形图问题的总结。
> * [视野总和](#1-视野总和)
> * [柱形图中的最大矩形](#2-柱状图中的最大矩形)
> * [盛最多水的容器](4.3%20数组与滑动窗口.md)
> * [接雨水问题](3.3%20接雨水问题.md)
> * [视野总和](#1-视野总和):利用了栈内元素的数量计算问题。
> * [柱形图中的最大矩形](#2-柱状图中的最大矩形):利用的是**出栈序列**。这组序列构成了可能的最大矩形。
> * [盛最多水的容器](4.3%20数组与滑动窗口.md):利用了反向贪心思想。
> * [接雨水问题](3.3%20接雨水问题.md):单调栈解法也是利用了**出栈序列**。这个序列的左右边界能够形成一个容器。双指针解法利用了反向贪心思想。
> * [接雨水问题2](3.3%20接雨水问题.md)
>
> 其它类型的单调栈
> * [求最大区间](#3-求最大区间):利用的**出栈的序列**。表示一个可能的最大值区间。
> * [132模式](#4-132-模式):利用了其有序性。
## 1 视野总和
@@ -34,6 +39,9 @@
1. 设置一个单调递减栈
2. 当入栈的的时候,栈内的人肯定能看到该元素。
> 利用了栈内元素的数量,解决问题。
### 算法分析
* 时间复杂度为O(N)
@@ -85,7 +93,7 @@ int FieldSum(vector<int>& v)
### 算法实现
```
```C++
int largestRectangleArea(vector<int>& heights) {
heights.push_back(-1);/同理,我们希望栈中所有数据出栈,所以给数组最后添加一个负数
stack<int> st;
@@ -108,6 +116,9 @@ int largestRectangleArea(vector<int>& heights) {
if (tmp > ret)
ret = tmp;
}
// 把最后出栈的元素入栈,将其高度改成当前的高度。
// 表示当前元素之前从top-i都比现在元素要高。
// 这方法太秀了,只能背下来吧。
st.push(top);
heights[top] = heights[i];
}