直方图最大面积 ---- DP

来源:互联网 发布:端口号80 编辑:程序博客网 时间:2024/05/22 04:50
Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given height = [2,1,5,6,2,3],

return 10.


解法一

使用动态规划,用left[i]表示第i个柱子可以最多向左延伸至第left[i]个柱子,形成一个矩形,right[i]则表示向右延伸。遍历两次,分别计算出这两个数组。再遍历一次,即可求出所有的柱子可以形成的最大的矩形面积。为了减少边界的判断,可以使用哨兵,在两端添加两个柱子高度都为-1.

#include <iostream>using namespace std;int heights[] = { 2,1,5,6,2,3 };/* get left[] & right[] */void GetLR(int & len, int* & left, int* & right){//get left[] firstlyleft[0] = 0;for (int i = 1; i < len; i++){int temp = i;while (heights[i] <= heights[temp - 1]){temp = left[temp - 1];if (temp == 0)break;}left[i] = temp;}//and then get right[]right[len - 1] = len - 1;for (int i = len - 2; i >= 0; i--){int temp = i;while (heights[i] <= heights[temp + 1]){temp = right[temp + 1];if (temp == len - 1)break;}right[i] = temp;}}int GetMaxRectangle(int & len){int* left = new int[len];int* right = new int[len];GetLR(len, left, right);int ans = 0;//the answerint t;for (int i = 0; i < len - 1; i++){t = heights[i] * (right[i] - left[i] + 1);ans = (ans > t) ? ans : t;}return ans;}int main(){int len = sizeof(heights) / sizeof(int);cout << "The largest rectangle is: " << GetMaxRectangle(len) << endl;// 10return 0;}

方法二


在网上发现另外一个使用一个栈的O(n)解法,代码非常简洁,栈内存储的是高度递增的下标。对于每一个直方图高度,分两种情况。1:当栈空或者当前高度大于栈顶下标所指示的高度时,当前下标入栈。否则,2:当前栈顶出栈,并且用这个下标所指示的高度计算面积。而这个方法为什么只需要一个栈呢?因为当第二种情况时,for循环的循环下标回退,也就让下一次for循环比较当前高度与新的栈顶下标所指示的高度,注意此时的栈顶已经改变由于之前的出栈。

#include <iostream>#include <stack>#include <algorithm>using namespace std;int heights[] = { 2,1,5,6,2,3 };int GetMaxRectangle(int & len){stack<int> s;int ans = 0;//the answerfor (int i = 0; i < len; i++){if (s.empty() || heights[s.top()] < heights[i])s.push(i);else{int cur = s.top();//the current index you will calculates.pop();int width = s.empty() ? i : i - s.top() - 1;ans = max(ans, width*heights[cur]);i--;}}while (!s.empty()){int cur = s.top();s.pop();int width = s.empty() ? len : len - s.top() - 1;ans = max(ans, width*heights[cur]);}return ans;}int main(){int len = sizeof(heights) / sizeof(int);cout << "The largest rectangle is: " << GetMaxRectangle(len) << endl;// 10return 0;}







题目来自: http://www.acmerblog.com/largest-rectangle-in-histogram-6117.html

1 0
原创粉丝点击