lintcode:直方图最大矩形覆盖

来源:互联网 发布:flash文字特效软件 编辑:程序博客网 时间:2024/04/30 04:02

给出的n个非负整数表示每个直方图的高度,每个直方图的宽均为1,在直方图中找到最大的矩形面积。


以上直方图宽为1,高度为[2,1,5,6,2,3]


最大矩形面积如图阴影部分所示,含有10单位


样例

给出 height = [2,1,5,6,2,3],返回 10


(1)
暴力破解法的思路:求出所有矩阵的面积,可以用右边界和左边界之差,乘以两边界之间的最小高度。(计算最大面积,则需要从左向右遍历所有点作为右边界),从第一个索引开始,记为i,另外一个索引从i开始向右移动,记为j,找出在 [ i .. j] 范围内最低的高度,记为H,那么面积等于 H(j-i+1)遍历完以后找出最大的面积即可。

//但是这样会超时

int findmin(vector<int> &height,int x,int y){if(x==y)return x;int minh=x;for(int i=x+1;i<=y;i++){if(height[minh]>height[i])minh=i;}return minh;}int largestRectangleArea(vector<int> &height) {    int max=0,s=0;    for(int i=0;i<height.size();i++)            {        for(int j=i;j<height.size();j++)    //注意单个矩阵的面积也要计算,所以重从=i开始        {            int h=findmin(height,i,j);                s=(j-i+1)*height[h];            if(s>max)                max=s;        }    }    return max;}

(2)用栈存储单调递增正序列的下标,与暴力破解法不同之处:它计算的矩阵的面积的右边界是局部的最高点(每次用i-1来表示,因为i是比栈顶元素高度小的下标,所以i-1就是局部最高点的下标),左边界就是从栈顶到栈底各元素的下标(注意下标相同时表示矩阵的宽是1),矩阵的高度就是栈顶到栈底的各个元素的高,用一个max记录最大矩形面积,每次求出一个最大面积就与max比较一次。到最后就得到最大面积。还要注意的是遍历的点i对应的最大矩形,是stack.pop(),也就是它的前一个点i-1作为右边界时的最大矩形,所以i要循环到height.length。当i循环到height.length()时,若栈中还有元素,就还要进行计算矩阵面积还有要注意,计算矩形宽度的时候,要考虑最高点弹出栈后栈是否为空:如果是,那么宽度w应该赋值i(因为本轮的栈顶一定比上一次的局部峰值小,所以应该取全长)。其它情况下,w = i-1-stack.top()。

大概过程见代码注释:

class Solution {public:/** @param height: A list of integer* @return: The area of largest rectangle in the histogram/int largestRectangleArea(vector &height) {int maxh=0;stackst; //存放递增高度序列的下标for(int i=0;i<=height.size();i++) //用i遍历全部数组{int nowh= (i == height.size()) ? 0 : height[i]; //若下标为height.size()时,其高度置为0while( !st.empty() && nowh <= height[st.top()] )//若当前的高度小于或等于栈顶的高度时{int h=height[st.top()]; //矩阵的高度为栈顶元素的高度            ///////这个很重要////            st.pop();               //将栈顶元素弹出            //要先将栈顶元素弹出,因为若左边界元素是栈底元素长度要取数组全长            //而不是当前长度到栈顶的长度            int w;            if(st.empty())      //若此时栈空                w=i;            //取全部长度,而不应该取            else                //否则宽度为i-1-st.top();                w=i-1-st.top();            maxh=max(maxh,w*h);     //记录下最大面积        }//执行完这个循环后栈为空,或栈顶元素的高度小于i的高度        st.push(i);              //将i再压入栈中    }    return maxh;}};

0 0
原创粉丝点击