题目:
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
Example:
Input: [2,1,5,6,2,3]
Output: 10
描述:
所给数组表示直方图的各个位置高度,每个位置宽为1,求图中面积最大矩阵的面积
分析:
第一印象应该是找个线性时间的算法,但是没想出来,
题目也没给数据范围,都不知道最优解的复杂度什么级别,
先用n^2的试一试,发现果然会超时,其实只有最后两组样例没过...,见代码一
然后再发现,只有第一个点,或者值递增的点作为起点,所得到的值才可能最大,然后试一下,(见代码二),竟然卡过去了,1600+MS,...
应该还有思路,能够大幅度优化,
后边再想吧
---------------
2019.06.09
今天学习了一下大神的解法,用到了单调栈(代码三),跟之前某道题非常像(点这里),不过当时的解法不够简洁,
对于这道题来说,自己私下里想的时候,稍微有点感觉,但是总觉得思维在哪里没有突破,所以虽然当时A过去了,但是还觉得不够,现在刷题又不是只为了数量,而是锻炼思维能力,这个单调栈,算是接触到了,算是
代码一:(时间复杂度O(N^2),超时)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if (!heights.size()) {
return 0;
}
int result = 0;
for (int i = 0; i < heights.size(); ++ i) {
int min_index = i;
for (int j = i; j < heights.size(); ++ j) {
if (heights[j] < heights[min_index]) {
min_index = j;
}
int sum = heights[min_index] * (j - i + 1);
result = max(result, sum);
}
}
return result;
}
};
代码二:(最坏时间复杂度O(N^2),1600+MS卡秒过了...)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if (!heights.size()) {
return 0;
}
vector<int> start;
start.push_back(0);
for (int i = 1; i < heights.size(); ++ i) {
if (heights[i - 1] < heights[i]) {
start.push_back(i);
}
}
int result = 0;
for (int i = 0; i < start.size(); ++ i) {
int min_index = start[i];
for (int j = start[i]; j < heights.size(); ++ j) {
if (heights[j] < heights[min_index]) {
min_index = j;
}
int sum = heights[min_index] * (j - start[i] + 1);
result = max(result, sum);
}
}
return result;
}
};
代码三:(最好时间复杂度O(n))
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
int result = 0;
stack<int> start;
for (int i = 0; i < heights.size(); ++ i) {
while (!start.empty() && heights[i] <= heights[start.top()]) {
int index = start.top();
start.pop();
result = max(result, heights[index] * (start.empty() ? i : i - start.top() - 1) );
}
start.push(i);
}
return result;
}
};