题目如下:(https://leetcode.com/problems/largest-rectangle-in-histogram/)

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.

题目似乎很简单,只要求出直方图中最大的矩形面积即可。然而最最单纯的O(n2)算法显然会跪(别人试过,我就不作死了……)。

有两类思路,分别如下:

Part One

提示说用栈,然而并没有想出如何使用。看懂别人的思路后再写,总觉得略微无聊……还是在此用自己的话复述一下吧。

(以下所有图片来自http://blog.csdn.net/doc_sgl/article/details/11805519

题目要求需要找面积最大的矩形,这个矩形的高为直方图中某柱高,我们可以认为矩形是由一个柱向两侧扩展得到的。

题中的直方图可以形象地理解为“波”,在一个波峰附近第一个高度下降的柱(下图中的t)会限制其左侧比它高的柱(记某柱为z)形成矩形的宽度,又由于t是该波峰第一个下降的柱形,故左侧比它高的柱z形成的矩形宽度为t与z横坐标之差(由于后续操作形成的波并不是连续的柱,此处实际上应为t-z前一个柱横坐标-1),这样就得到了一个矩形面积。

如上操作后,柱z已经完成了它的使命(已经求出由它形成的矩形的面积,左右的矮柱也不需要它的高度),当t左侧所有高柱都完成使命后,t成了相对高的柱,可以看作与前面的更矮的柱又在形成一个又矮又宽的波峰(图中阴影),遇到更矮的i之后,重复前面的操作即可得到所有柱生成的矩形的面积。

于是,我们可以用栈保存一串连续上升的柱(波上升的部分),当遇到矮柱时,求前面每个高柱形成的矩形的面积,然后将这个没用的高柱弹出。最后将矮柱压入,作为下一个波的上升部分。这个过程扫描一遍,算法复杂度为O(n)。

/************************如果觉得上面写的清晰可以忽略下面的部分**************************/

针对样例输入,可以进行如下分析:

1.将柱0压栈,。

2.柱1更矮,求柱0形成的矩形面积,将柱1压栈。

3.柱1柱2柱3高度递增,进栈。

4.柱4比2,3矮:柱3求面积,出栈;柱2求面积,出栈。

5.柱4柱5进栈。

6.最后求栈中剩余柱形成矩形的面积(相当于最后有一个高度为0的柱,使其前面的柱出栈)。

(似乎应该在这里再说一下,以上所有图片来自http://blog.csdn.net/doc_sgl/article/details/11805519 )//2015/11/13日补

/************************懂了上面,下面的代码其实不重要了**************************/

class Solution {
public:
int largestRectangleArea(vector<int>& height) { height.push_back(); //使最后栈中剩余柱出栈
stack<int> serHeight; //储存高度递增的柱的栈
int maxArea = ; //最大面积
int curArea = ; //当前矩形面积 for (int i = ; i < height.size(); i++)
{
if (serHeight.empty() || height[serHeight.top()] <= height[i]) //高度上升,进栈
{
serHeight.push(i);
}
else
{
//将高矩形出栈,求其生成的矩形面积
while (height[serHeight.top()] > height[i])
{
int cur = serHeight.top();
serHeight.pop();
if (serHeight.empty())
{
curArea = height[cur] * i;
maxArea = (maxArea > curArea) ? maxArea : curArea;
break;
}
curArea = height[cur] * (i - serHeight.top() - );
maxArea = (maxArea > curArea) ? maxArea : curArea;
} serHeight.push(i);
}
}
return maxArea;
}
};

Part Two

一个更容易想到的思路是先判断每个柱左右两边不比它矮的最远柱,然后可以更容易地算出由当前柱形成的矩形面积。

利用动态规划的思想,可以利用前面已确定的最远高柱更新当前需要找的柱。比如下面代码中若l[i]左边的l[i]-1比i还要高,那么可以用l[l[i] - 1]更新l[i],这样可以加快查找高柱的速度。

class Solution {
public:
int largestRectangleArea(vector<int>& height) {
int maxArea = ; //最大面积
int curArea = ; //当前面积
int s = height.size(); //柱形个数
int *l = new int[s]; //储存不比当前柱矮的最左端柱
int *r = new int[s]; //储存不比当前柱矮的最右端柱 //先找储存不比当前柱矮的最左端柱
for (int i = ; i < s; i++)
{
l[i] = i; //自己不比自己矮
//利用已存过的l[i]判断是否找到最左端
while (l[i] && height[l[i] - ] >= height[i])
{
l[i] = l[l[i] - ];
}
}
//再找储存不比当前柱矮的最右端柱
for (int i = s - ; i >= ; i--)
{
r[i] = i;
while ((r[i] - s + ) && height[r[i] + ] >= height[i])
{
r[i] = r[r[i] + ];
}
}
//计算由当前柱生成的矩形面积,更新最大面积
for (int i = ; i < s; i++)
{
curArea = height[i] * (r[i] - l[i] +);
maxArea = (maxArea > curArea) ? maxArea : curArea;
} return maxArea;
}
}

附:

日常膜:http://www.cnblogs.com/lustralisk/p/branch-3.html

生日快乐:http://blog.sina.com.cn/s/blog_1495db3970102w3f8.html

 

 

数据结构与算法(1)支线任务3——Largest Rectangle in Histogram的更多相关文章

  1. LeetCode 笔记系列 17 Largest Rectangle in Histogram

    题目: Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar he ...

  2. 【LeetCode】84. Largest Rectangle in Histogram

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  3. Maximal Rectangle&Largest Rectangle in Histogram

    这两天在做leetcode的题目,最大矩形的题目以前遇到很多次了,一直都是用最笨的方法,扫描每个柱子,变换宽度,计算矩形面积,一直都以为就这样O(n2)的方法了,没有想到居然还有研究出了O(n)的算法 ...

  4. Largest Rectangle in Histogram及二维解法

    昨天看岛娘直播解题,看到很经典的一题Largest Rectangle in Histogram 题目地址:https://leetcode.com/problems/largest-rectangl ...

  5. 47. Largest Rectangle in Histogram && Maximal Rectangle

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  6. leetcode Largest Rectangle in Histogram 单调栈

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052343.html 题目链接 leetcode Largest Rectangle in ...

  7. 关于LeetCode的Largest Rectangle in Histogram的低级解法

    在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...

  8. leetcode之Largest Rectangle in Histogram

    问题来源:Largest Rectangle in Histogram 问题描述:给定一个长度为n的直方图,我们可以在直方图高低不同的长方形之间画一个更大的长方形,求该长方形的最大面积.例如,给定下述 ...

  9. LeetCode之“动态规划”:Maximal Square && Largest Rectangle in Histogram && Maximal Rectangle

    1. Maximal Square 题目链接 题目要求: Given a 2D binary matrix filled with 0's and 1's, find the largest squa ...

随机推荐

  1. Nginx转发地址解决跨域问题

    什么是跨域问题 在一个服务器A里放置了json文件,另一个服务器B想向A发送ajax请求,获取此文件,会发生错误. Chrome提示: XMLHttpRequest cannot load ***** ...

  2. java虚拟机之垃圾回收算法

    标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...

  3. PP 创建BOM

    转自 http://blog.csdn.net/u012369651/article/details/19190939 一.最终结果预览. 二.创建过程. 使用到的事务码 CS01 创建BOM CS0 ...

  4. FZU 1759 欧拉函数 降幂公式

    Description   Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000 ...

  5. const成员变量初始化总结

    const可以用来声明常量也就是说他的值不能被修改: const成员必须在定义的时候同时初始化,不能进行赋值 如 const int a:a的值不能修改,不能给它赋值,如何才能让它一开始就拥有一个值? ...

  6. ubuntu kylin 16.04系统的基本安装

    系统版本:ubuntu kylin 16.04 硬件状况:500G HDD+120G SSD 已安装操作系统:WIN 10专业版(craked) ——WIN 10系统是装在SSD的第一个盘符内的.以前 ...

  7. python built-in zip()

    zip([iterable, ...]) 返回一个list ,list里的元素是元组tuple.第i个元组内的元素是所有iteralbe中第i个元素组成的. 当所有的iterable拥有同样的长度的时 ...

  8. MyBatis学习(二)

    前言 昨天的博客简单的记录了MyBatis的起源.作用.配置以及一个简单的查询例子.写到一半的时候,觉得已经学会了MyBatis,可是全写完的时候才发现,如果多个参数查询,如何表的名字与类字段名不一样 ...

  9. JavaScript中常见的数组操作函数及用法

    JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...

  10. [综]隐马尔可夫模型Hidden Markov Model (HMM)

    http://www.zhihu.com/question/20962240 Yang Eninala杜克大学 生物化学博士 线性代数 收录于 编辑推荐 •2216 人赞同 ×××××11月22日已更 ...