Question

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 = 10unit.

Example

Given height = [2,1,5,6,2,3],
return 10.

Solution 1 -- Naive

For each start point i

  For each end point j

    minHeight = min height between i and j

    result = max{result, (j - i + 1) * minHeight}

Time Complexity O(n2)

 public class Solution {
/**
* @param height: A list of integer
* @return: The area of largest rectangle in the histogram
*/
public int largestRectangleArea(int[] height) {
// write your code here
if (height == null || height.length < 1)
return 0;
int start, end, minHeight, result = Integer.MIN_VALUE;
for (start = 0; start < height.length; start++) {
minHeight = height[start];
for (end = start; end < height.length; end++) {
minHeight = Math.min(minHeight, height[end]);
result = Math.max(result, (end - start + 1) * minHeight);
}
}
return result;
}
}

Solution 2 -- Increasing Stack

根据木桶原理,面积由最矮的高度决定。我们把问题转换为

For 决定矩阵高度的那根最矮木头 i

  看 i 往左最远能延伸到什么地方 indexLeft

  看 i 往右最远能延伸到什么地方 indexRight

  best = max{best, height[i] * (indexRight - indexLeft + 1)}

所以我们要找:

往左走第一个比height[i]小的数

往右走第一个比height[i]小的数

这种题典型的用递增/递减栈实现。

 public class Solution {
/**
* @param height: A list of integer
* @return: The area of largest rectangle in the histogram
*/
public int largestRectangleArea(int[] height) {
// write your code here
if (height == null || height.length < 1)
return 0;
int result = 0;
Stack<Integer> increasingStack = new Stack<Integer>();
// Attention here i <= length
for (int i = 0; i <= height.length; i++) {
int currentValue = ((i == height.length) ? -1 : height[i]);
while (!increasingStack.isEmpty() && height[increasingStack.peek()] >= currentValue) {
int currentHeight = height[increasingStack.pop()];
int left = increasingStack.size() > 0 ? increasingStack.peek() : -1;
int right = i;
result = Math.max(result, (right - left - 1) * currentHeight);
}
increasingStack.push(i);
}
return result;
}
}

注意,这里除了要计算以每个pop出来的元素为高的最大面积,还要计算每个未被pop出来的元素为高的最大面积。因此技巧在于最后多加一个元素-1,由于输入元素均大于等于0,所以当-1要push入栈时,栈里所有的元素都会被pop出来。

还要注意,当前值等于栈顶值时也要做出栈操作。

每个元素只入栈/出栈一次,因此时间复杂度是O(1)

Largest Rectangle in Histogram 解答的更多相关文章

  1. 刷题84. Largest Rectangle in Histogram

    一.题目说明 题目84. Largest Rectangle in Histogram,给定n个非负整数(每个柱子宽度为1)形成柱状图,求该图的最大面积.题目难度是Hard! 二.我的解答 这是一个 ...

  2. LeetCode 笔记系列 17 Largest Rectangle in Histogram

    题目: Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar he ...

  3. 47. Largest Rectangle in Histogram && Maximal Rectangle

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  4. 【LeetCode】84. Largest Rectangle in Histogram

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  5. leetcode Largest Rectangle in Histogram 单调栈

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052343.html 题目链接 leetcode Largest Rectangle in ...

  6. 关于LeetCode的Largest Rectangle in Histogram的低级解法

    在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...

  7. leetcode之Largest Rectangle in Histogram

    问题来源:Largest Rectangle in Histogram 问题描述:给定一个长度为n的直方图,我们可以在直方图高低不同的长方形之间画一个更大的长方形,求该长方形的最大面积.例如,给定下述 ...

  8. 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 ...

  9. 84. Largest Rectangle in Histogram

    https://www.cnblogs.com/grandyang/p/4322653.html 1.存储一个单调递增的栈 2.如果你不加一个0进去,[1]这种情况就会输出结果0,而不是1 3.单调递 ...

随机推荐

  1. HDU5044---Tree 树链剖分

    大致题意:add1 u v   u到v路径上所有点的权值加上k,add2  u 到v路径上所有边的权值加上k 最后输出所有点的权值,边的权值..树链剖分预处理然后来个线性O(n)的操作.刚开始用线段树 ...

  2. PHP关于时区问题

    最近在学习PHP过程中发现PHP中的格式化时间戳比北京时间晚了8个小时,上网搜索发现原来是时区不对,解决办法是:      1.永久修改           更改php.ini文件中的data.tim ...

  3. Codeforce 216 div2

    D 只要搞清楚一个性质:确定了当前最大和次大的位置,局面就唯一确定了; 根据这个性质设计dp,统计到达该局面的方法数即可. E 询问的要求是: 求有多少个区间至少覆盖了询问的点集中的一个; 转化成逆命 ...

  4. 如何让程序(如java Hello)只启动一次?

    如何让程序(如java Hello)只启动一次? 摘自http://bbs.csdn.net/topics/50488704 总结一下,关于让Java程序只运行一个实例的问题,其实质是JVM之间通信的 ...

  5. swift 点击button改变其内填充图片,达到选中的效果

    先看下效果: 点击后: 实现:在页面拖一个button,然后在所在页面声明其变量和一个点击事件 声明: @IBOutlet weak var BtnZiDong: UIButton! 点击事件函数: ...

  6. Android BLE开发之Android手机与BLE终端通信

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 近期穿戴设备发展得非常火.把相关技术也带旺了,当中一项是BLE(Bluetooth Low Energy).B ...

  7. swing入门例子

    // a simple exmple that can show the basis of swing------------------------------------------------- ...

  8. UICollectionView的基本使用

    这个控件,看起来与UITableView有点像,而且基本的用法也很相像哦!!! 我们来看看API: #pragma mark - UICollectionViewDataSource // 指定Sec ...

  9. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

  10. 用sp_change_users_login消除Sql Server的孤立用户

    异常详细信息: System.Data.SqlClient.SqlException: 拒绝了对对象 'zwj_EnterpriseActivities' (数据库 'Ntours',架构 'dbo' ...