题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例
- 示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
- 示例 2:
输入: heights = [2,4]
输出: 4
提示
- 1 <= heights.length <=105
- 0 <= heights[i] <= 104
解题思路
- 当使用暴力解法时,会出现超时现象。
- 使用单调栈,即栈内元素按非递减压入,每当碰到比栈顶元素小的元素时,进行出栈操作直至栈顶元素小于等于指定元素;
- 在出栈的同时,进行面积的计算;
- 对数组遍历结束后,若栈内元素不为空,再次进行出栈并计算面积。
代码
- 单调栈
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int v_len = heights.size();
int *stk = new int[v_len];
int area_max, stk_pos, area, left, right, i, h, temp, temp_pos;
area_max = 0;
stk_pos = 0;
for(i = 0; i < v_len;){
if(stk_pos == 0 || heights[i] >= heights[stk[stk_pos-1]]){
if(heights[i] != 0){
stk[stk_pos++] = i;
}
i++;
continue;
}
while(stk_pos > 0 && heights[i] < heights[stk[stk_pos-1]]){
right = i;
left = stk[stk_pos-1];
h = heights[left];
stk_pos--;
temp_pos = left;
temp = heights[left];
while(left > 0 && heights[left-1] >= temp){
if(heights[temp_pos] == heights[left-1]){
stk_pos--;
}
left--;
}
// cout << left << " " << right << " " << h << endl;
area = (right-left) * h;
area_max = area_max > area ? area_max : area;
}
}
while(stk_pos > 0){
right = i;
left = stk[stk_pos-1];
h = heights[left];
stk_pos--;
temp_pos = left;
temp = heights[left];
while(left > 0 && heights[left-1] >= temp){
if(heights[temp_pos] == heights[left-1]){
stk_pos--;
}
left--;
}
// cout << left << " " << right << " " << h << endl;
area = (right-left) * h;
area_max = area_max > area ? area_max : area;
}
return area_max;
}
};
- 暴力解法
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int v_len = heights.size();
int i, left, right, area, area_max;
area_max = 0;
for(i = 0; i < v_len; i++){
left = right = i;
while(left-1 >= 0 && heights[left-1] >= heights[i]){
left--;
}
while(right+1 < v_len && heights[right+1] >= heights[i]){
right++;
}
area = (right-left+1) * heights[i];
// cout << area << endl;
area_max = area_max > area ? area_max : area;
}
return area_max;
}
};
提交结果
总结
- 单调栈思想,可以用于方便的解决距离一个值最近但比其低或者高的问题。