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)

最新文章

  1. CCNA网络工程师学习进程(3)常规网络设计模型与基本的网络协议
  2. Eclipse汉化后怎么改回英文版(可切换中英文)
  3. OpenGL教程
  4. js原型对象与Java类的比较
  5. JSON与DataTable(DataSet)相互转化
  6. shell中使用sqlplus及调试相关
  7. 内存四个领域,变量声明和定义,注册,c内联汇编,auto,堆,不变,静态变量
  8. Docker系列教程02-MongoDB默认开启鉴权
  9. 【easy】215. Kth Largest Element in an Array 第K大的数
  10. ECMA Script 6_字符串_扩展_字符 是4字节还是2字节?_模板字符串
  11. 代码漏洞扫描描述Cross Site History Manipulation解决办法[dongcoder.com]
  12. IDEA tomcat8 控制台日志乱码
  13. 在win10中解决 你要以何方式打开此 .xlsx
  14. Parallels Desktop 重装系统
  15. git(转载谢谢)
  16. 【Java】 剑指offer(57-2) 为s的连续正数序列
  17. dojo/domReady! 中感叹号的作用
  18. 大型运输行业实战_day09_1_日期转换与My97DatePicker插件使用
  19. 【bzoj5210】最大连通子块和 动态dp
  20. python通过swig调用静态库

热门文章

  1. 传阿里整合资源,进军O2O市场
  2. JAVA中运用数组的四种排序方法
  3. Quartz集成springMVC 的方案一
  4. python高级编程:缓存
  5. OCP-1Z0-051-题目解析-第28题
  6. [Angular 2] Using the @Inject decorator
  7. asp.net的3个经典范例(ASP.NET Starter Kit ,Duwamish,NET Pet Shop)学习资料
  8. Asp.Net EF Code First 简单入门
  9. Asp.Net HttpApplication请求管道与Session(二)
  10. GDI+编程的10个基本技巧(转)