菜鸡每日一题系列打卡84天
每天一道算法题目
小伙伴们一起留言打卡
坚持就是胜利,我们一起努力!
题目描述(引自LeetCode)
给定n个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为1。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为1,给定的高度为[2,1,5,6,2,3]。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为10个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
题目分析
这道题目最容易想到的是暴力法,通过双重for循环枚举高度(或者宽度),从而得到柱状图中最大的矩形,但基于暴力搜索的时间复杂度为O(n^2),我们需要对此进行优化。
这时候就需要用到一种经典的数据结构——单调栈,其实就是一种栈,只不过其中的元素是有序的。值得注意的是,通过单调栈维护小于柱子i的高度值,需要注意栈为空时设置哨兵。
话不多说,上代码!
代码实现
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) return 0;
int length = heights.length;
int[] left = new int[length];
int[] right = new int[length];
Arrays.fill(right, length);
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < length; i++) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) right[stack.pop()] = i;
left[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
int result = 0;
for (int i = 0; i < length; i++) {
int tmp = (right[i] - left[i] - 1) * heights[i];
if (tmp > result) result = tmp;
}
return result;
}
}
代码分析
对代码进行分析,程序采用了单调栈进行实现,每一个位置只会入栈一次(在枚举到它时),并且最多出栈一次,因此单调栈的时间复杂度为O(n);而就空间而言,采用了额外的数组空间和单调栈空间,空间复杂度为O(n)。
执行结果
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到