直方图内最大矩形
题目描述
给定一个数组heights,长度为n,height[i]是在第i点的高度,那么height[i]表示的直方图,能够形成的最大矩形是多少?
1.每个直方图宽度都为1
2.直方图都是相邻的
3.如果不能形成矩形,返回0即可
4.保证返回的结果不会超过2^31-1
方法一:暴力解法
解题思路
对于本题目的求解,直接遍历每一个直方图,将其高度作为矩形的高度,然后分别向前、向后延申,得到可能的矩形的最大长度,然后计算每个矩形的面积,最后取最大值即可。
解题代码
import java.util.*;
public class Solution {
public int largestRectangleArea (int[] heights) {
//总宽度
int n=heights.length;
int res=0;
for(int i=0;i<n;i++)
{
int start=-1;
//从后往前找到第一个小于当前的高度,记为start
for(int j=i-1;j>=0;j--)
{
if(heights[j]<heights[i])
{
start=j;
break;
}
}
int end=n;
//从前往后找到第一个小于当前的高度,记为end
for(int j=i+1;j<n;j++)
{
if(heights[j]<heights[i])
{
end=j;
break;
}
}
//根据start、end得到以当前高度为高的最大矩形面积,取所有可能的最大值
res=Math.max(res,(end-start-1)*heights[i]);
}
return res;//返回结果
}
}
复杂度分析
时间复杂度:两层循环,因此时间复杂度为。
空间复杂度:使用常数级内存地址空间,因此空间复杂度为。
方法二:栈思想
解题思路
对于本题目的求解,可以使用单调栈,只要栈顶元素比当前大,则可以统计以栈顶元素为高的最大面积。由于单调栈内元素是不减的,可以确定矩形右边界为当前元素前一位,而左边界为pop操作以后栈顶元素的后一位。如果栈中元素为空,说明0为左边界,因为单调不递减,后面的肯定比它大,前面的比它小,若为空,则说明左边界为0。如果遍历完之后,单调栈还不为空,则以同样的方式继续统计面积值,最后返回最大值即可。
解题代码
import java.util.*;
public class Solution {
public int largestRectangleArea (int[] heights) {
//总宽度
int n=heights.length;
//新建单调栈
ArrayDeque<Integer> stack=new ArrayDeque<>();
int res=0;
for(int i=0;i<n;i++)
{
//只要栈顶元素比当前大,则可以统计以栈顶元素为高的最大面积
while(!stack.isEmpty()&&heights[stack.peek()]>heights[i])
{
//由于单调栈内元素是单调不递减的,L到i-1之间的高度一定大于等于curHeight
int curHeight=heights[stack.pop()];
//如果栈中元素为空,说明0到i-1之间的高度均大于等于curHeight
int L=stack.isEmpty()?0:stack.peek()+1;
res=Math.max(res,(i-L)*curHeight);
}
stack.push(i);
}
//如果遍历完之后,单调栈还不为空,则继续统计可能的最大面积
while(!stack.isEmpty())
{
int curHeight=heights[stack.pop()];
int L=stack.isEmpty()?0:stack.peek()+1;
res=Math.max(res,(n-L)*curHeight);
}
return res; // 返回面积最大值
}
}
复杂度分析
时间复杂度:一层循环,因此时间复杂度为。
空间复杂度:使用大小为N的栈,因此空间复杂度为。