庞果英雄会---寻找直方图中面积最大的矩形---编程挑战
题目链接:http://hero.pongo.cn/home/index
这里给出一个线性算法和一个平方算法,第一个算法没有问题,挑战成功。第二个算法测试了很多数据但是失败,有大神路过,恳请点拨。
#include <iostream> using namespace std; int g[500],index[500]; int max_rect(int x[], int n) { int s = 0, maxsum = 0, i, j, h, area; g[0] = index[0] = 0; for (i = 0; i <= n; i++) { h = i == n ? 0 : x[i]; for (j = i; g[s] > h; j = index[s--]) { area = (i - index[s]) * g[s]; if (area > maxsum ) { maxsum = area; } } if (h > g[s]) { g[++s] = h; index[s] = j; } } return maxsum; } int main() { int ia[]={2,1,4,5,1,3,3}; cout<<max_rect(ia,7)<<endl; return 0; }
这里说一下第二个算法的思路:
最近面积的右边界,其高度一定比右边的高度要高,否则不满足最大。找到每一列高度大于其右边高度的直方图,往左寻找每一个可能的
左边界,计算每一个可能的面积,更新最大。
有一个小技巧是在最后一个元素后面添加哨兵0,这样就可以处理右边界问题了。
#include <iostream> #include <vector> using namespace std; vector<int> height; int maxsum=0; int largestRectangleArea(vector<int> &height) { int len=height.size(); height.push_back(0); for(int i=0;i<len;i++) { if(height[i]<=height[i+1])continue; int mmin=99999; for(int j=i;j>=0;j--) { mmin=mmin<height[j]?mmin:height[j]; int area=mmin*(i-j+1); if(area>maxsum)maxsum=area; } } return maxsum; } int main() { int ia[]={7,2,1,4,5,1,3,3}; for(int i=0;i<8;i++)height.push_back(ia[i]); cout<<largestRectangleArea(height)<<endl; return 0; }