数据结构与算法(1)支线任务3——Largest Rectangle in Histogram
题目如下:(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的更多相关文章
- LeetCode 笔记系列 17 Largest Rectangle in Histogram
题目: Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar he ...
- 【LeetCode】84. Largest Rectangle in Histogram
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- Maximal Rectangle&Largest Rectangle in Histogram
这两天在做leetcode的题目,最大矩形的题目以前遇到很多次了,一直都是用最笨的方法,扫描每个柱子,变换宽度,计算矩形面积,一直都以为就这样O(n2)的方法了,没有想到居然还有研究出了O(n)的算法 ...
- Largest Rectangle in Histogram及二维解法
昨天看岛娘直播解题,看到很经典的一题Largest Rectangle in Histogram 题目地址:https://leetcode.com/problems/largest-rectangl ...
- 47. Largest Rectangle in Histogram && Maximal Rectangle
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- leetcode Largest Rectangle in Histogram 单调栈
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052343.html 题目链接 leetcode Largest Rectangle in ...
- 关于LeetCode的Largest Rectangle in Histogram的低级解法
在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...
- leetcode之Largest Rectangle in Histogram
问题来源:Largest Rectangle in Histogram 问题描述:给定一个长度为n的直方图,我们可以在直方图高低不同的长方形之间画一个更大的长方形,求该长方形的最大面积.例如,给定下述 ...
- 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 ...
随机推荐
- 根据内存布局定位的一个fastdfs坑
在使用fastdfs时,编写数据上传代码时,遇到一个坑.最终根据指针对应的内存布局定位到一个其client API的一个坑,值得记录一下.具体是在 tracker_connect_server() 这 ...
- linux系统下根据端口查看进程
第一步:lsof -i:端口号 第二步:根据显示的pid号,查询对应应用程序. ps -ef | grep pid (这里的pid是:23466)
- "错误消息 401.2。: 未经授权: 服务器配置导致登录失败。"的解决办法
[详细报错如下]: “/”应用程序中的服务器错误. 访问被拒绝. 说明: 访问服务此请求所需的资源时出错.服务器可能未配置为访问所请求的 URL. 错误消息 401.2.: 未经授权: 服务器配置导致 ...
- JS和Android交互
//本地webview写法 webview = (WebView) findViewById(R.id.webview); webview.loadUrl("http://192.168.1 ...
- (转) Spring框架笔记(二十五)——NamedParameterJdbcTemplate与具名参数(转)
在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参数绑定. 在 Spring JDBC 框架中, 绑定 ...
- POJ 1014 Dividing
Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 66032 Accepted: 17182 Descriptio ...
- Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...
- php 上传大文件配置upload_max_filesize和post_max_size选项
php 上传大文件配置upload_max_filesize和post_max_size选项 (2014-04-29 14:42:11) 转载▼ 标签: php.ini upload _files[f ...
- 如何配置网络使得宿主机能够访问VM数据库?
https://www.zhihu.com/question/23955166 背景:公司内外网区分,不能同时上,局域网内得手动切换两个网络,分别访问外网或者内网,ip是动态获取的.现在本机上装有vm ...
- easyui datagrid 动态添加columns属性
公司在项目设计的时候,有一个需求,就是查出来的表的字段不唯一,一张表的字段可能是三个,也可能是五个,但是却要把它显示到页面,这个给我做ui的带来一点麻烦.因为以前一般用easyui 的datagrid ...