一个直方图是由许多矩形组成,在给定的直方图中找出最大的矩形面积。
输入:
输入包含若干测试用例。每个测试用例描述直方图,并开始与整数 n,表示它由组成的矩形的数量。你可以假设那 1 < = n < = 100000。然后按照 n 个整数 h1,......,hn,其中 0 < = hi< = 1000000000。这些数字表示左到右的顺序在直方图的矩形的高度。每个矩形的宽度是 1.0跟随输入的最后一个测试。
输出:
对于每个测试用例输出在单独的一行中指定直方图的最大矩形面积。请记住,此矩形必须在共同的基准线对齐。
代码:
import java.util.Scanner;
import java.util.Stack;
import com.sun.java_cup.internal.internal_error;
public class test_02 {
/**
* 求直方图最大矩形
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
test_02 t = new test_02();
int[] a={};
int num=scanner.nextInt();
for(int i=0;i<num&&scanner.hasNext()!=0;i++){
a[i]=scanner.nextInt();
}
System.out.println(t.largestRectangleArea(a));
}
public int largestRectangleArea(int[] height) {
Stack<Integer> s = (Stack<Integer>) new Stack<Integer>();
int max_area = 0; // 最大矩形面积
int tp; // 栈顶
int area_with_top;
int i = 0;
int n = height.length;
while (i < n) {
if (s.empty() || height[s.peek()] <= height[i]) {
s.push(i++);
} else {
tp = s.pop();
area_with_top = height[tp] * (s.empty() ? i : i - s.peek() - 1);
max_area = Math.max(max_area, area_with_top);
}
}
while (!s.empty()) {
tp = s.pop();
area_with_top = height[tp] * (s.empty() ? i : i - s.peek() - 1);
max_area = Math.max(max_area, area_with_top);
}
return max_area;
}
}
理解:感觉首先用栈存储起来,依次输入矩形的高,首先你第一个输入的数是作为栈顶存储起来的,后面的如果比栈顶大,那么就继续存储进栈中,否则就把
第一个栈顶弹出来,因为如果后面矩形高度的比栈顶还小,就不可能继续围成大矩形了,如果发生了这个情况,栈顶压出来,此时右边界肯定=现在栈的
长度,左边界=你的栈顶(也就是即将出栈的矩形所在的地方)然后继续比较,但是存在while 循环,所以对于每个出栈的矩形算出面积,最后求算出来
最大面积就是答案。