LeetCode Notes_#84 柱状图中最大的矩形
Contents
题目
解答
方法1:暴力
class Solution {
public int largestRectangleArea(int[] heights) {
int max_area = 0;
for(int i = 0; i < heights.length; i++){
int min_height = heights[i];
for(int j = i; j < heights.length; j++){
int width = j - i + 1;
min_height = Math.min(min_height, heights[j]);
max_area = Math.max(max_area, width * min_height);
}
}
return max_area;
}
}
复杂度分析
时间复杂度:O(n!)
,n是height.length,i=0时,内层循环进行了n次...i=n-1时,内层循环进行了1次。所以复杂度是n * (n-1) * (n-2) * ... 1 = n!
空间复杂度:O(1)
方法2: 单调栈
【柱状图中最大的矩形】单调栈入门,使用单调栈快速寻找边界 - 柱状图中最大的矩形
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
//left[i]是下标为i的柱子向左搜索得到的第一个比它矮的柱子
int[] left = new int[n];
//right[i]是下标为i的柱子向右搜索得到的第一个比它矮的柱子
int[] right = new int[n];
//right数组初始化,n其实已经超出了heights的范围n-1,其实下标为n的柱子是一个虚拟的,高度为1的柱子
Arrays.fill(right, n);
//单调栈初始化
Stack<Integer> mono_stack = new Stack<Integer>();
for(int i = 0; i < n; ++i){
//维护单调递增栈的结构,保证新加入的元素小于目前的栈顶元素
while(!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]){
//由于是从前向后进行遍历的,所以i位置当然就是第一次遇到的比mono_stack要矮的柱子
right[mono_stack.peek()] = i;
//如果下标为i的柱子比栈顶柱子矮,直接push(i)就会破坏单调递增规则,所以需要不断弹出栈顶柱子,直到push(i)不会破坏单调递增规则
mono_stack.pop();
}
//由于还没有push(i),i柱子的左边第一个比他矮的柱子其实就是栈顶的柱子
left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek());
mono_stack.push(i);
}
int ans = 0;
//通过left[],right[]遍历所有可能性,从而计算出最大值
for(int i = 0; i < n; ++i){
ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
}
return ans;
}
}