一个小练习题目,也是高频面试题
给定一个非负数组arr,代表直方图
返回直方图的最大长方形面积
题目分析
代码,不应不用多解释
package dataStructure.danDiaoZhan.practice;
import java.util.Stack;
import static dataStructure.danDiaoZhan.GetNearLess.printArr2D;
/**
* 给定一个非负数组arr,代表直方图
* 返回直方图的最大长方形面积
*/
public class MaxAreaOfRectangle {
public static int maxArea(int[] nums) {
if(nums == null || nums.length == 0) {
return 0;
}
int maxArea = 0;
int[][] nearLessArr = getNearLess(nums);
for(int i = 0; i < nums.length; i++) {
int[] nearLess = nearLessArr[i];
//leftBound我们可以利用一下我们一步的公式,我们下一步的公式是rightBound - leftBound + 1
//如果左边没有比它小的,我们刚好可以利用这个-1,公式中的+1可以省略
//所以这个就不要了,注释了
//int leftBound = nearLess[0] == -1? 0 : nearLess[0] + 1;
int rightBound = nearLess[1] == -1? nums.length - 1 : nearLess[1];
int width = rightBound - nearLess[0];
int maxAreaCur = width * nums[i];
maxArea = Math.max(maxArea, maxAreaCur);
}
return maxArea;
}
public static int[][] getNearLess(int[] nums) {
int[][] nearLessArr = new int[nums.length][2];
//这里依然可以进行简化,不用LinkedList或者ArrayList,而直接放数组下标
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < nums.length; i++) {
//如果栈不为空并且栈顶大于等于当前元素就替代
//等于的时候弹出栈顶,这个时候栈顶弹出算的右边第一个比他小的数肯定不对
//不过没事,我们后面弹出最后一个相等值的时候是可以算对的,这些相等值计算的时候是可以彼此联通的,不影响最终结果
while(!stack.isEmpty() && nums[stack.peek()] >= nums[i]) {
int popIndex = stack.pop();
//如果栈不为空,说明它原来在栈里压着其他元素,这个元素就是左边第一个比他小的
nearLessArr[popIndex][0] = stack.isEmpty()? -1 : stack.peek();
nearLessArr[popIndex][1] = i;
}
stack.push(i);
}
//剩余元素独立结算
while(!stack.isEmpty()) {
int popIndex = stack.pop();
nearLessArr[popIndex][0] = stack.isEmpty()? -1 : stack.peek();
//最后结算的元素右边都没有 比它小的,不然它就被弹出了
nearLessArr[popIndex][1] = -1;
}
printArr2D(nearLessArr);
return nearLessArr;
}
public static void main(String[] args) {
//int[] nums = {3,2,4,2,5};
int[] nums = {3,1,3,0,3};
int maxArea = maxArea(nums);
System.out.println(maxArea);
}
}
欢迎交流