Leetcode单调栈题目小总结

有关讲解: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。

Leetcode单调栈题目小总结_第1张图片
代码是这:

class Solution {
public:
    int sumSubarrayMins(vector& A) {
        int sz = A.size();
        int mod = 1e9 + 7;
        long long ret = 0;
        stack 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到最大,虽然超时了。。。

你可能感兴趣的:(Leetcode)