[LeetCode#84]Largest Rectangle in Histogram
Problem:
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.
Analysis:
This problem is very very tirkcy, but elegnat! The idea behind the solution is super powerful, you should clearly think about it.
Possible solution:
For each element in the height array.
1. go right until nums[left] < cur_height
2. then go left until nums[right] < cur_height
Then caculated the area of rectanlge of the encolsed region: cur_height * [(right-1) - (left-1) - 1]
They key point for each element is to find out the left broader and right broader.
Apparently, this method would take O(n^2). Can we do it more smartly?
iff height[cur-1]'s boundary is clear, if we still compare all elements before height[cur-1], which were already compared by height[cur-1]. There must be way to avoid those uncessary comparison. Algorithm:
Take advantage of a stack, the stack's elments are always in the "small-to-large" order.
Step 1: scan the height array from left to right.
(While) Once the current element <= top element at the stack. we pop out an element.
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
...
}
Note: this can guarantee all elements in the stack array in the ascending order. For each poped element, we can get its left border and right border, through following way.
1. the stack still have elements.
(not included)left border: the current top element in the stack, since it is the first element smaller than the poped element.
(not included)right border: the current element height[i]. Since only when "height[i] <= height[stack.peek()]", the poped element appears. The rectangle's area: (right border-1) - (left border+1) + 1 = (i - 1) - (stack.peek()+1) + 1 = (i - stack.peek() + 1) * cur_height. 2. the stack does not have elements.
(included)left border: It means all elements appear before the poped element are actually larger than the poped element, we could start from the first element of the array.
(not included)right border: The current element height[i]. Since only when "height[i] <= height[stack.peek()]", the poped element appears. The rectangle's area : (right border-1) - (left border) + 1 = (i - 1) - (0) + 1 = i * cur_height Implementation:
-------------------------------------------------------------------------------------------------
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
int cur_height = height[stack.pop()];
cur_max = stack.isEmpty() ? i*cur_height : (i-stack.peek()-1)*cur_height;
max = Math.max(max, cur_max);
}
stack.push(i);
}
------------------------------------------------------------------------------------------------- One idea should be kept in mind:
When we push a element into the stack, we pop out all elements larger than it.
Thus when we need to get left broder, we can directly get from stack.peek() after the poped operation. Since for all elements appeared after the pushed element, must take the pushed element as left border. Those poped elements would not affect them. <What a great idea!> Note: In this problem, we actually set one 0 at left side and one 0 at right side of the height array.
0 [height] 0.
For the above question, we must take care the case when all height elements were scaned, but there are still elements in the stack, thus we must use the right fake border. nums[height] = 0.
Solution:
public class Solution {
public int largestRectangleArea(int[] height) {
if (height == null || height.length == 0)
return 0;
Stack<Integer> stack = new Stack<Integer> ();
int max = 0, cur_max = 0;
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
int cur_height = height[stack.pop()];
cur_max = stack.isEmpty() ? i*cur_height : (i-stack.peek()-1)*cur_height;
max = Math.max(max, cur_max);
}
stack.push(i);
}
while (!stack.isEmpty()) {
int cur_height = height[stack.pop()];
cur_max = stack.isEmpty() ? height.length*cur_height : (height.length-stack.peek()-1)*cur_height;
max = Math.max(max, cur_max);
}
return max;
}
}
[LeetCode#84]Largest Rectangle in Histogram的更多相关文章
- LeetCode 84. Largest Rectangle in Histogram 单调栈应用
LeetCode 84. Largest Rectangle in Histogram 单调栈应用 leetcode+ 循环数组,求右边第一个大的数字 求一个数组中右边第一个比他大的数(单调栈 Lee ...
- [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- LeetCode 84. Largest Rectangle in Histogram 直方图里的最大长方形
原题 Given n non-negative integers representing the histogram's bar height where the width of each bar ...
- [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- leetCode 84.Largest Rectangle in Histogram (最大矩形直方图) 解题思路和方法
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [leetcode]84.Largest Rectangle in Histogram ,O(n)解法剖析
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- 【LeetCode】84. Largest Rectangle in Histogram 柱状图中最大的矩形(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调栈 日期 题目地址: https://leetc ...
- 84. Largest Rectangle in Histogram
https://www.cnblogs.com/grandyang/p/4322653.html 1.存储一个单调递增的栈 2.如果你不加一个0进去,[1]这种情况就会输出结果0,而不是1 3.单调递 ...
- 刷题84. Largest Rectangle in Histogram
一.题目说明 题目84. Largest Rectangle in Histogram,给定n个非负整数(每个柱子宽度为1)形成柱状图,求该图的最大面积.题目难度是Hard! 二.我的解答 这是一个 ...
随机推荐
- Maven浅析-2 什么是Maven
1.简单点讲:Maven就是一个项目构建工具.它可以生成一个artifact(component),还可以帮我们管理项目依赖(如附加的组件Filters等). 2.从整体讲:Maven也可以看作一个项 ...
- CSS排版页面
创建CSS文件如下: @charset "utf-8"; /* CSS Document */ *{ margin:0px; padding:0px; border:0px; } ...
- PHP金字塔的输出
相信学习语言的最初的时候,学到循环的时候,开始一定有种摸不着头脑,想砸电脑的冲动吧 这里就是记录我当初学习的时候,为了通过这个循环,学习的金字塔的输出 1.首先,要了解一个金字塔的输出就要去看它的表达 ...
- 雷鸟(Thunderbird)收取Gmail出错,收到警告邮件
如题,每次打开thunderbird都会收到以下提醒邮件,后来发现,只要将thunderbird中和google服务有关的插件卸载掉就可以了 We prevented the sign-in atte ...
- mysql连接错误:Cannot get hostname for your address
问题 环境:win7 + 64Bit + 本地mysql5.6 问题:navicat连接本地mysql数据库,提示“Cannot get hostname for your address”,但是连接 ...
- [DEncrypt] DESEncrypt--加密/解密帮助类 (转载)
点击下载 DESEncrypt.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.DESEncrypt加密2.DESEncrypt解密看下面代码吧 /// <summary> / ...
- T-SQL切割字符串方法小结 2
有表tb, 如下: id value ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc 欲按id,分拆value列, 分拆后结果如下: id value -- ...
- oracle数据库误删恢复方法
一.如果只是误删部分数据或者某条数据可以通过 1.select * from 误删除的表明 as of timestamp to_Date('恢复年月日 时分秒', '恢复时间格式') ...
- 3 委托、匿名函数、lambda表达式
委托.匿名函数.lambda表达式 在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法.C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方 ...
- [Lua]索引极致,form.lua
local form = {_tag = 'form'} function form.build(tag, super) local target = { _tag = tag, _super = s ...