LeetCode(84): 柱状图中最大的矩形
Hard!
题目描述:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
解题思路:
这道题让求直方图中最大的矩形,http://fisherlei.blogspot.com/2012/12/leetcode-largest-rectangle-in-histogram.html这里有一种很好的优化方法,就是遍历数组,每找到一个局部峰值,然后向前遍历所有的值,算出共同的矩形面积,每次对比保留最大值。
C++解法一:
// Pruning optimize
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
int res = ;
for (int i = ; i < height.size(); ++i) {
if (i + < height.size() && height[i] <= height[i + ]) {
continue;
}
int minH = height[i];
for (int j = i; j >= ; --j) {
minH = min(minH, height[j]);
int area = minH * (i - j + );
res = max(res, area);
}
}
return res;
}
};
还有一种比较流行的解法,是利用栈来解,详见http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html,但是经过仔细研究,其核心思想跟上面那种剪枝的方法有异曲同工之妙,这里维护一个栈,用来保存递增序列,相当于上面那种方法的找局部峰值。
我们可以看到,直方图形面积要最大的话,需要尽可能的使用连续的矩形多,并且最低一块的高度要高。有点要木桶原理一样,总是最低的那块板子决定桶的装水量。那么既然需要用单调栈来做,首先要考虑到底用递增栈,还是用递减栈来做。
增栈是维护递增的顺序,当遇到小于栈顶元素的数就开始处理,而递减栈正好相反,维护递减的顺序,当遇到大于栈顶元素的数开始处理。那么根据这道题的特点,我们需要按从高板子到低板子的顺序处理,先处理最高的板子,宽度为1,然后再处理旁边矮一些的板子,此时长度为2,因为之前的高板子可组成矮板子的矩形 ,因此我们需要一个递增栈,当遇到大的数字直接进栈,而当遇到小于栈顶元素的数字时,就要取出栈顶元素进行处理了,那取出的顺序就是从高板子到矮板子了,于是乎遇到的较小的数字只是一个触发,表示现在需要开始计算矩形面积了,为了使得最后一块板子也被处理,这里用了个小trick,在高度数组最后面加上一个0,这样原先的最后一个板子也可以被处理了。由于栈顶元素是矩形的高度,那么关键就是求出来宽度,那么跟之前那道Trapping Rain Water一样,单调栈中不能放高度,而是需要放坐标。由于我们先取出栈中最高的板子,那么就可以先算出长度为1的矩形面积了,然后再取下一个板子,此时根据矮板子的高度算长度为2的矩形面积,以此类推,知道数字大于栈顶元素为止,再次进栈,很是巧妙!关于单调栈问题可以参见http://www.cnblogs.com/grandyang/p/8887985.html
C++解法二:
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
int res = ;
stack<int> st;
height.push_back();
for (int i = ; i < height.size(); ++i) {
if (st.empty() || height[st.top()] < height[i]) {
st.push(i);
} else {
int cur = st.top(); st.pop();
res = max(res, height[cur] * (st.empty() ? i : (i - st.top() - )));
--i;
}
}
return res;
}
};
我们可以将上面的方法稍作修改,使其更加简洁一些:
C++解法二:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int res = ;
stack<int> st;
heights.push_back();
for (int i = ; i < heights.size(); ++i) {
while (!st.empty() && heights[st.top()] >= heights[i]) {
int cur = st.top(); st.pop();
res = max(res, heights[cur] * (st.empty() ? i : (i - st.top() - )));
}
st.push(i);
}
return res;
}
};
LeetCode(84): 柱状图中最大的矩形的更多相关文章
- LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)
84. 柱状图中最大的矩形 84. Largest Rectangle in Histogram
- Java实现 LeetCode 84 柱状图中最大得矩形
84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的 ...
- LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)
题目描述 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的 ...
- leetcode 84. 柱状图中最大的矩形 JAVA
题目: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高 ...
- [LeetCode] 84. 柱状图中最大的矩形
题目链接 : https://leetcode-cn.com/problems/largest-rectangle-in-histogram/ 题目描述: 给定 n 个非负整数,用来表示柱状图中各个柱 ...
- Leetcode84. 柱状图中最大的矩形(单调栈)
84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足 ...
- LeetCode---84. 柱状图中最大的矩形(hard)
题目:84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 示例: 输入: [2,1,5 ...
- 【LeetCode】84. Largest Rectangle in Histogram 柱状图中最大的矩形(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调栈 日期 题目地址: https://leetc ...
- LeetCode 84. Largest Rectangle in Histogram 单调栈应用
LeetCode 84. Largest Rectangle in Histogram 单调栈应用 leetcode+ 循环数组,求右边第一个大的数字 求一个数组中右边第一个比他大的数(单调栈 Lee ...
随机推荐
- mui单选和多选框
具体见代码: <!doctype html> <html> <head> <meta charset="UTF-8"> <ti ...
- .netcore 写日志(使用NLog,log4net)
参考地址: NLog:http://www.cnblogs.com/linezero/p/Logging.html Log4Net:http://www.cnblogs.com/linezero/p/ ...
- day 5 - 1 字典(dict)
dict dict key 必须是不可变数据类型,可哈希value:任意数据类型 dict 优点:使用二分查询来搜索数据存储了大量的关系型数据特点:无序的 数据类型划分:可变数据类型,不可变数据类型不 ...
- 微信小程序之内嵌网页(webview)
设置权限 要在小程序中访问外部网页,需要先设置允许访问的业务网站的域名.让我们先登录小程序平台管理后台页面,进入“设置” => "开发设置",可以看到这边多出来了一块“业务域 ...
- SFTP远程连接服务器上传下载文件-vs2010项目实例
本项目仅测试远程连接服务器,支持上传,下载文件,更多功能开发请看API自行开发. 环境:win7系统,vs2010 vs2010项目实例下载地址:CSDN下载 如果没有CSDN积分,百度网盘下载(密码 ...
- 方法join()使用详解
在线程的常见方法一节中,已经接触过join()方法的使用. 在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将早于子线程结束.这时,如果主线程想等子线程执行完成才结束,比 ...
- 关于树的常见操作-C++面试
#include <iostream> using namespace std; //树的存储结构与设计 struct BitNode { int data; BitNode* leftC ...
- 【转】python3解析库lxml
转自:http://www.cnblogs.com/zhangxinqi/p/9210211.html 阅读目录 1.python库lxml的安装 2.XPath常用规则 (1)读取文本解析节点 (2 ...
- 【转】浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
- 带你十分钟快速构建好 SpringBoot + SSM 框架
目前最主流的 java web 框架应该是 SSM,而 SSM 框架由于更轻便与灵活目前受到了许多人的青睐.而 SpringBoot 的轻量化,简化项目配置, 没有 XML 配置要求等优点现在也得到了 ...