[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! 二.我的解答 这是一个 ...
随机推荐
- MyBatis返回主键,MyBatis Insert操作返回主键
MyBatis返回主键,MyBatis Insert操作返回主键 >>>>>>>>>>>>>>>>> ...
- C#一般处理程序获取Session
如果需要用ajax去动态校验验证码,如何获取Session保存的值呢? 你需要做两步: 一.在你的一般处理程序中添加命名空间 (using System.Web.SessionState;) 二.在你 ...
- java web hello world
首先在eclipse 里面创建一个java 动态项目, 记住路径,这里是直接通过根目录直接访问的webContent目录下面 的文件, 创建好后 ,在本地配置Tomcat服务器, 将server加入到 ...
- BroadcastReceiver和Intetnt的理解 Day34
BroadcastReceiver和Intetnt的理解 Day34 mobile4.0 短信监控 问题堆栈 1. 下载开源项目View.网址自己fork一下 2. ContentProvider原理 ...
- JavaScript的push(),pop(),concat()方法
push 方法 将新元素添加到一个数组中,并返回数组的新长度值. arrayObj.push([item1 [item2 [. . . [itemN ]]]]) 参数 arrayObj 必选项.一个 ...
- Win32中GDI+应用(三)---Graphics类
在我理解看来,Graphics是一个device context和你的drawing conetent之间的一个中介.它存储了device context的相关属性,以及drawing content ...
- 理解MySQL——索引与优化(转)
写 在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页 面大小为4K,并存储100条记录.如果没有索引,查 ...
- 交叉编译tslib1.4
cross-compiler: arm-linux-gcc V4.2.1 source code: tslib-1.4.tar.gz #tar zxvf tslib-1.4.tar.gz #./aut ...
- PHP表单常用正则表达式(URL、HTTP、手机、邮箱等)
<?php /** * @description: 正则表达式匹配 */ class Regex { /** * @手机号 */ public static function Phone($su ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...