1.題目
給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度爲 1 。
求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
以上是柱狀圖的示例,其中每個柱子的寬度爲 1,給定的高度爲 [2,1,5,6,2,3]。
圖中陰影部分爲所能勾勒出的最大矩形面積,其面積爲 10 個單位。
示例:
輸入: [2,1,5,6,2,3]
輸出: 10
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
2.題解
暴力(C++過不了)
爲什麼要寫下暴力法,是因爲其他方法不過就是在暴力法的基礎上運用一些存儲記錄的方法,以空間換時間罷了!
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int size = heights.size();
if(size == 0) return 0;
int res = 0;
for(int i = 0; i < size; i++)
{
int L = i;
int cur = heights[i];
while( L > 0 && heights[ L - 1 ] >= cur)
L--;
int R = i;
while(R < size - 1 && heights[R + 1] >= cur)
R++;
res= max(res,(R - L + 1)*cur);
}
return res;
}
};
單調棧
思路:
我們發現在暴力求解中,我們要做的就是尋找每個柱體不能再向左或向右拓展時,最大的面積,暴力求法中,我們用線性時間求得。
那麼我們能否通過單調棧來再優化查找邊界的時間。
優化:
單調遞增棧,當前的高度嚴格小於棧頂元素的高度時出棧。計算面積。
思路參考https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/84-by-ikaruga/
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int ans = 0;
vector<int> st;
heights.insert(heights.begin(), 0); //首尾加0,方便處理
heights.push_back(0);
for (int i = 0; i < heights.size(); i++)
{
while (!st.empty() && heights[st.back()] > heights[i])
{
int cur = st.back();
st.pop_back();
int left = st.back() + 1;
int right = i - 1;
ans = max(ans, (right - left + 1) * heights[cur]);
}
st.push_back(i);
}
return ans;
}
};