题目:
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.
For example,
Given height =[2,1,5,6,2,3],
return10.
题意:
给定n个非负整数表示直方图的条高,其中每个条的宽度为1,求直方图中最大矩形的面积。
上面是一个柱状图,给定高度=[2,1,5,6,2,3],每个柱状图的宽度为1。
最大的矩形显示在阴影区域,它的面积=10个单位。
例如,
给定高度= (2、1、5、6,2,3]。
return10。
解题思路:
这里有两种解法
第一种就是一个一个的比较,声明一个max变量,然后使用双重循环,第一重循环是遍历数组,在第一重循环里获取数值,第二重循环是建立在第一重循环上,然后从当前i开始,比较后面数字与当前选取的数字大小。
代码:
/*
* 暴力破解法,直接双重循环比较
*/
public static int largestRectangleArea(int[] height) {
if(height == null) {
return 0;
}
int max = 0;
for(int i = 0;i <= height.length-1;i++) {
int width = 0;
int minHeight = height[i];
System.out.println(minHeight);
for(int j = i;j <= height.length-1;j++) {
width++;
System.out.println("width="+width);
System.out.println("height[j]="+height[j]);
minHeight = Math.min(minHeight,height[j]);
System.out.println("minHeight="+minHeight);
max = Math.max(max, minHeight*width);
System.out.println("max="+max);
}
}
return max;
}
第二种思路是使用栈来解决
1.用height[]构造一个升序栈,构造过程中计算面积
2.如果当前height[i]大于栈顶元素,则入栈;
3.若小于栈顶元素,则将栈顶元素弹出并做记录弹出几次,并计算以弹出元素作为高度的面积,留下最大值ret,直到满足height[i]大于栈顶元素,再将弹出的元素以height[i]重新入栈
下面给出例子:
1:2入栈,当前栈元素为{2}
2.此时1入栈,进行比较发现比2小,则2弹出,count+1, 记录res = 2*1,然后1替代2入栈,现在栈里元素为{1,1}
3.这时5入栈,现在栈里元素为{1,1,5}
4.这时6入栈,现在栈里元素为{1,1,5,6}
5.这时2入栈时进行比较,则6出栈,count =1,res =max(2,6*1) = 6; 这时候 发现5还是比2大,所以5也要出栈,这时候count=2,res = max(6,2*5) = 10 。然后继续比较发现栈里没有比2大的了,最后用分别2代替5,6进栈,同时2也进栈。此时栈里元素为{1,1,2,2,2}
6.此时3进栈,最后形成了升栈序列{1,1,2,2,2,3}
7.最后再让栈序依次出栈,同时更新res的值
最后输出res值最大为10。整个过程很好的利用了栈的原理。下面给出代码:
/*
* 使用栈来解决
*/
public static int largestRectangleArea2(int[] height) {
if(height == null) {
return 0;
}
int res = 0;
Stack<Integer> stack = new Stack<Integer>();
for(int i = 0;i < height.length; i++) {
if(stack.isEmpty() || stack.peek() <= height[i]) {
stack.push(height[i]);
}
else {
int count = 0;
while(!stack.isEmpty() && stack.peek() > height[i]) {
count++;
res = Math.max(res, count*stack.peek());
stack.pop();
}
while(count-- > 0) {
stack.push(height[i]);
}
stack.push(height[i]);
}
}
int count = 1;
while(!stack.isEmpty()) {
res = Math.max(res, count*stack.peek());
stack.pop();
count++;
}
return res;
}