题目:biubiu
题意:给出连续的长柱,求出长柱构成的最大矩形的面积。
构成矩形如果左边的矩形比较高,那么左边这一个柱就可以合并,如果左边出现一个低于,那么这个柱就是界限,同样找到右边的界限,然后就可以找到矩形面积。
如何找两边的界限,可以使用单调栈。
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<unordered_map>
#include<stack>
#include<algorithm>
using namespace std;
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int>l(n), r(n);
stack<int>p;
for (int i = 0; i < n; i++) {
while (!p.empty() && heights[p.top()] >= heights[i])
p.pop();
l[i] = p.empty() ? -1 : p.top();
p.push(i);
}
while (p.size())
p.pop();
for (int i = n - 1; i >= 0; i--) {
while (!p.empty() && heights[p.top()] >= heights[i])
p.pop();
r[i] = p.empty() ? n : p.top();
p.push(i);
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans = max(ans, (r[i] - l[i] - 1) * heights[i]);
}
return ans;
}
};
int main() {
vector<int>nums;
while (1) {
vector<int>nums;
while (1) {
int x;
cin >> x;
nums.push_back(x);
if (cin.get() == '\n')
break;
}
Solution s;
cout << s.largestRectangleArea(nums) << endl;
}
return 0;
}
优化:
在确定左边边界时同时确定右边界,单调栈弹出说明压入的元素比当前的栈顶元素小,可以说是当前的右边界。但是并不一定正确,如果有相同的元素,可以会对边界照成影响,但是不影响结果。
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<unordered_map>
#include<stack>
#include<algorithm>
using namespace std;
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int>l(n), r(n,n);
stack<int>p;
for (int i = 0; i < n; i++) {
while (!p.empty() && heights[p.top()] >= heights[i]) {
r[p.top()] = i;
p.pop();
}
l[i] = p.empty() ? -1 : p.top();
p.push(i);
}
/*while (p.size())
p.pop();
for (int i = n - 1; i >= 0; i--) {
while (!p.empty() && heights[p.top()] >= heights[i])
p.pop();
r[i] = p.empty() ? n : p.top();
p.push(i);
}*/
int ans = 0;
for (int i = 0; i < n; i++) {
ans = max(ans, (r[i] - l[i] - 1) * heights[i]);
}
return ans;
}
};
int main() {
vector<int>nums;
while (1) {
vector<int>nums;
while (1) {
int x;
cin >> x;
nums.push_back(x);
if (cin.get() == '\n')
break;
}
Solution s;
cout << s.largestRectangleArea(nums) << endl;
}
return 0;
}