题目描述
The largest rectangle is shown in the shaded area, which has area = 10
unit.
Example:
Input: [2,1,5,6,2,3]
Output: 10
算法实现:
关键在于思路,具体实现并不难。
首先考虑到如果是一个顺序排列,问题会比较简单,如2,3,4,5只需要比较2*4,3*3, 4*2 , 5*1即可
对于题中这样有升序和降序的情况,只需要在降序时比较前面造成不能升序的序列即可
以example为例
- 先看到第一条2,面积为2;
- 加入第二条后,第二条为1,比前一条小,那么如果两条合在一起就是1*2 = 2
- 加入第三条后,第三条5比前一条大,如果其和前几条合在一起就是1*3=3,我们把不和前几条放在一起的情况置后考虑
- 加入第四条后,6 > 4, 同上面3: 1*4 = 4;
- 加入第五条后,2 < 6, 说明前面一部分一段内是升序,而到此处升序截至,为此,我们比较可能的结果到升序处6*1,5*2。到这里5,6这两条值大于2的情况就都考虑完了,可将其作为高为2的序列考虑
- 依次将2,3加入序列
- 现在各条作为升序{1,1,2,2,2,3}考虑即可
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(heights.empty())return 0;
int n = heights.size();
int smin, result, num;
stack<int> s;
s.push(heights[0]);
result = heights[0];
smin = heights[0];
for(int i = 1; i < n; i ++){
if(heights[i] < s.top()){
num = 0;
while(!s.empty() && heights[i] < s.top()){
num ++;
result = max(s.top()*num, result);
// cout << i << ":" << s.top() << "," << num << "," << result << endl;
s.pop();
}
if(s.empty())smin = heights[i];
for(int j = 0; j < num; j ++)s.push(heights[i]);
}
s.push(heights[i]);
result = max(result, smin*(i + 1));
// cout << i << ": " << smin << "," << result << endl;
}
num = 0;
while(!s.empty()){
num ++;
// cout << num << "," << s.top() << endl;
result = max(result, s.top()*num);
s.pop();
}
return result;
}
};