思路:两种方法:1.暴力法;2.辅助栈
先来法2:
此时初始化max_area=0;
此时max_area=0;
此时max_area=0;
此时cur_area=((2-1)-0)*7=7;max_area=7;
此时cur_area=((2-1)-(-1))*6=12;max_area=12;
此时max_area=12;
此时cur_area=((3-1)-(-1))*5=20;max_area=20;
理解了思路之后,后续的同理不再画出。
特别需要注意的是:
为了处理最后一根柱子,对heights进行扩充,即:
heights.push_back(0);//为最后一根柱子准备的
时间复杂度:O(n),n个数字每个会被压栈弹栈各一次。
空间复杂度:O(n),用来存放栈中元素。
完整代码如下(这个代码写出来感觉还挺佩服自己的哈哈哈):
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);//为最后一根柱子准备的
stack<int>index_stack, height_stack;
index_stack.push(-1);
height_stack.push(-1);
int max_area = 0;
int cur_area = 0;
for (int i = 0; i < heights.size(); i++) {
while (index_stack.top() != -1)
{
if (heights[i] > height_stack.top())
break;
else
{
int temp_height = height_stack.top();
height_stack.pop();
index_stack.pop();
cur_area = ((i - 1) - index_stack.top())*temp_height;
max_area = max(cur_area, max_area);
}
}
index_stack.push(i);
height_stack.push(heights[i]);
}
return max_area;
}
};
再来看法1暴力法:
首先,我们可以想到,两个柱子间矩形的高由它们之间最矮的柱子决定的。
因此,我们可以考虑所有两两柱子之间形成的矩形面积,该矩形的高为它们之间最矮柱子的高度,宽为它们之间的距离,这样可以找到所要求的最大面积的矩形。
时间复杂度:O(n3),我们需要使用 O(n)的时间找到O(n2)枚举出来的所有柱子对之间的最矮柱子。
空间复杂度:O(1),只需要常数空间的额外变量。
代码如下:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int max_area = 0, cur_area = 0;
int min_height;
for (int i = 0; i < heights.size() - 1; i++)
for (int j = i + 1; j < heights.size(); j++)
{
for (int k = i; k <= j; k++)//找出区间[i,j]最矮的柱子
{
if (k == i)
min_height = heights[k];
else
min_height = min(min_height, heights[k]);
}
cur_area = min_height*(j - i + 1);
max_area = max(max_area, cur_area);
}
return max_area;
}
};
虽然,暴力法在leetcode中会显示超出时间限制,但是写还是要会写的。