[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! 二.我的解答 这是一个 ...
随机推荐
- Python教程:连接数据库,对数据进行增删改查操作
各位志同道合的同仁可以点击上方关注↑↑↑↑↑↑ 本教程致力于程序员快速掌握Python语言编程. 本文章内容是基于上次课程Python教程:操作数据库,MySql的安装详解 和python基础知识之上 ...
- [PDF] PDFOperation--C#PDF文件操作帮助类 (转载)
点击下载 PDFOperation.rar 这个类是关于PDFOperation的帮助类,主要是实现C#PDF的文件操作,具体实现功能如下1.构造函数2.私有字段3.设置字体4.设置页面大小5.实例化 ...
- 初学HTML5系列一:简单介绍
最近很闲,就想着学点东西,然后就瞄中了html5,以前只看过很简单的一些,这次是系统的学下,顺便也记录下.废话不多说,开始正题. 稍微介绍下html5,html5是W3C和WHATWG 合作的结果. ...
- Linux上安装KDE, Gnome和VNC
安装所需环境:需要至少256m的可用内存(128也可以不过有点卡)CentOS或类似OS(Debian的话改成apt-get应该也可以) 1,安装KDE 1 yum install kdepim 或安 ...
- Python:文件操作
#!/usr/bin/python3 str1 = input("请输入:") print("你输入的是:",str1) f=open("abc.tx ...
- vecor预分配内存溢出2
vector预分配内存溢出导致原始的 迭代器 失效 consider what happens when you add the one additional object that causes t ...
- Android中解析XML的方法
假设我要解析如下的XML文件: <?xml version="1.0" encoding="UTF-8"?> <books> <b ...
- Maven项目的目录结构
刚接触Maven没多长时间,实习时在的小公司很不规范,所有web项目都是dynamic web project搭建,没有用到项目构建,管理工具,导致了非常多的重复工作与低效. 先来看看Maven的功能 ...
- centos7 更改语言
vim /etc/locale.conf 修改 LANG="en_US.UTF-8"
- node 后台ajax文件(同时支持http、https)
var http = require("http"), Url = require("url"), querystring = require('queryst ...