题目
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
.
1. 暴力法:两层遍历,O(n^2)复杂度
2. 分治法:找到所有柱体中最小高度,那么最大矩形面积在如下三种情况里选取:
a. 最小柱体左侧的所有柱体所能构成的最大矩形面积;
b. 最小柱体右侧的所有柱体所能构成的最大矩形面积;
c. 所有柱体的个数乘以最小柱体高度。
a和b中的最大矩形面积可以递归求得。
如何获取最小高度的柱体,可以事先构造order-statistic tree,复杂度O(n),分治法复杂度O(nlgn),总体复杂度O(nlgn)
具体方法参考:http://www.geeksforgeeks.org/largest-rectangular-area-in-a-histogram-set-1/
3. 线性搜索:通过计算以每个柱体为最小柱体的最大矩形面积,来获取全局的最大矩形面积,利用栈的特性来保存当以某个柱体为最小柱体时所能达到的左侧边界和右侧边界。复杂度O(n)。
具体方法参考:http://www.geeksforgeeks.org/largest-rectangle-under-histogram/
这道题的思路还有很多,这个网页的Problem H里列举了很多:http://www.informatik.uni-ulm.de/acm/Locals/2003/html/judge.html,没有细看了。
代码
import java.util.Stack; public class LargestRectangleInHistogram { public int largestRectangleArea(int[] height) { int ret = 0; if (height == null) { return 0; } Stack<Integer> stack = new Stack<Integer>(); int N = height.length; for (int i = 0; i < N; ++i) { if (stack.isEmpty() || height[stack.peek()] <= height[i]) { stack.push(i); } else { int index = stack.pop(); int area = height[index] * (stack.isEmpty() ? i : i - stack.peek() - 1); ret = Math.max(ret, area); --i; } } while (!stack.isEmpty()) { int index = stack.pop(); int area = height[index] * (stack.isEmpty() ? N : N - stack.peek() - 1); ret = Math.max(ret, area); } return ret; } public static void main(String[] args) { LargestRectangleInHistogram lrih = new LargestRectangleInHistogram(); int[] height = new int[] { 6, 2, 5, 4, 5, 1, 6 }; System.out.println(lrih.largestRectangleArea(height)); } }