diff --git a/数据结构/3.1 单调栈.md b/数据结构/3.1 单调栈.md index d699323d..3062f997 100644 --- a/数据结构/3.1 单调栈.md +++ b/数据结构/3.1 单调栈.md @@ -69,4 +69,23 @@ for(int i = T.size() - 1; i >= 0; i--){ 1. 当前元素出栈的时候,说明当前元素是倒数第二小的元素。 -一般会采取怎样的操作呢?具体再总结。 \ No newline at end of file +## 问题总结 + +一般会采取怎样的操作呢?具体再总结。 + +> * [视野总和](#1-视野总和):利用了**栈内元素的数量计算问题**。 +> * [柱形图中的最大矩形](#2-柱状图中的最大矩形):利用的是**出栈序列**。这组序列构成了可能的最大矩形。 +> * [接雨水问题](3.3%20接雨水问题.md):单调栈解法也是利用了**出栈序列**。这个序列的左右边界能够形成一个容器。 +> * [接雨水问题2](3.3%20接雨水问题.md) +> +> 其它类型的单调栈 +> * [求最大区间](#3-求最大区间):利用的**出栈的序列**。表示一个可能的最大值区间。 +> * [132模式](#4-132-模式):利用了其**有序性**。 + +### 总结 + +综上所述主要有以上三种利用思想。 + +1. 针对栈内元素数量的利用。第一个问题,仅仅是简单的模拟。 +2. 针对有序性的利用。每次都是贪心的求得最大的3,反向求解第二大的元素。 +3. 针对出栈序列的利用。在递增栈和递减栈中,每一个出栈序列的两端,都是一个最大边界、或者最小边界,在边界中会形成问题的一个解序列。序列中的每个值,比两个边界大或者小。 \ No newline at end of file diff --git a/算法/A类:基本算法/6 贪心算法.md b/算法/A类:基本算法/6 贪心算法.md index 0d5bd7a4..5868a277 100644 --- a/算法/A类:基本算法/6 贪心算法.md +++ b/算法/A类:基本算法/6 贪心算法.md @@ -31,9 +31,22 @@ * 局部最优:它是当前步骤中所有可行性选择中最佳的局部选择。 * 不可取消:即选择一旦做出,在算法的后面步骤中就无法改变了。 +## 2 反向贪心思想 + +1. 正向贪心思想,每次都能选择最优的结果,最终能够选择所有最优子问题构成的最优解。 +2. 反向贪心思想,虽然无法确定当前的最优结果。但是每次都能排除掉最差的结果。通过一系列排除最差结果的方法,得到最后的最优解。 + +### 实例 + +* [二维数组的查找](../C类:问题类型算法/1.2%20二维数组查找.md) +* [盛最多水的容器](../B类:数据结构算法/4.3%20数组与滑动窗口.md) +* [接雨水问题](../B类:数据结构算法/3.3%20接雨水问题.md) + +以上三个问题,每次的谈心选择,不是选择当前步骤的最优解,而是排除不可能的最差情况。 -## 2 常见问题 + +## 3 常见问题 ### 分数背包问题 ### 最短路径问题 ### Dijkstra’s Algorithm diff --git a/算法/B类:数据结构算法/3.1 单调栈-局部顺序.md b/算法/B类:数据结构算法/3.1 单调栈-局部顺序.md index 90b10510..c19c170a 100644 --- a/算法/B类:数据结构算法/3.1 单调栈-局部顺序.md +++ b/算法/B类:数据结构算法/3.1 单调栈-局部顺序.md @@ -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& v) ### 算法实现 -``` +```C++ int largestRectangleArea(vector& heights) { heights.push_back(-1);/同理,我们希望栈中所有数据出栈,所以给数组最后添加一个负数 stack st; @@ -108,6 +116,9 @@ int largestRectangleArea(vector& heights) { if (tmp > ret) ret = tmp; } + // 把最后出栈的元素入栈,将其高度改成当前的高度。 + // 表示当前元素之前,从top-i都比现在元素要高。 + // 这方法太秀了,只能背下来吧。 st.push(top); heights[top] = heights[i]; }