有关讲解:http://www.cnblogs.com/grandyang/p/8887985.html
相关的题目有:
496. Next Greater Element I
503. Next Greater Element II
42. Trapping Rain Water
84. Largest Rectangle in Histogram
待补充
9.6:
昨天晚上做hulu笔试,第二题又用到了单调栈。原题目是:一组整数,要求求出所有符合:0 <=i <= j < sz的[i,j]中最大的数的和。
题目类似于leetcode:907。
代码是这:
class Solution {
public:
int sumSubarrayMins(vector<int>& A) {
int sz = A.size();
int mod = 1e9 + 7;
long long ret = 0;
stack<int> si;
si.push(-1);
for (int i = 0; i < sz; ++i) {
while (si.size() > 1 && A[si.top()] >= A[i]) {//注意为了防止重复,这里相等的话也要弹出。
int top = si.top();
si.pop();
ret += (((long long)(top - si.top()) * (i - top) % mod) * A[top] % mod);
ret %= mod;
}
si.push(i);
}
while (si.size() > 1) {
int top = si.top();
si.pop();
ret += (((long long)(top - si.top()) * (sz - top) % mod) * A[top] % mod);
ret %= mod;
}
return ret;
}
};
值得注意的是:注释哪里需要避免重复值的情况。
核心思路就是:对于每个值,我们计算以它为最小值的[i,j]范围有多少个。比如:
3 5 2 6
以2为最小值的范围有3 * 2个。(可以这么算,左边3 5 2,5 2, 2有3个,右边2 6, 2有两个,组合)。
这就涉及到单调栈的核心用法了:(结合84. Largest Rectangle in Histogram):
我们如果想要找出对于一组数中,对其中每个数,以它为最大(最小)值的范围是多大。这就可以用到单调栈。
比如这题:我们想要知道以每个数为最小值的范围是多大,就可以求出这些范围的最小数的和。
比如84最大矩形的题目:我们想要知道以每个数为最小值的范围是多大,我们就可以求出以它为高的矩形最长为多少。
(注意,这一题的重复值的处理)
另外说一句:对于这一题,我一开始是用滑动窗口来做的,分别取窗口大小由1到最大,虽然超时了。。。