84. Largest Rectangle in Histogram
題目網址:https://leetcode.cn/problems/largest-rectangle-in-histogram/
題意:給
n個非負整數, 用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰, 且寬度為1。返回柱狀圖中最大矩形的面積。


Solution 1:(TLE 無法通過)
想法:利用 Brute Force, 對於每一個
heights[i]的寬度即為左、右邊第一個< heights[i]的位置, 其寬度為right - left - 1(left、right都不包含在寬度中, 故要減一)
class Solution { |
- time:$O(n^2)$ ➔ for loop 中每一個
i皆需 $O(n)$ 去找到左、右邊第一個< heights[i]的位置 - space:$O(1)$ ➔ 只需常數空間
Solution 2:
想法:概念同 Solution 1, 利用 Monotonic Stack 來儲存 index, 維護一個遞增的 stack。一旦下一個元素
i的高度比stk.top()的高度要小, 則可以知道idx = stk.top()的右邊高度比它小的第一個位置是i, 而左邊高度比它小的第一個位置是把當前stk.top()給 pop 掉後的stk.top()。stk會不斷計算idx = stk.top()的 area, 並將stk.top()給 pop 掉, 直到heights[stk.top()] < heights[i], 詳情請看這篇的方法二e.g.
stk = [1, 3]
- 假設
idx = 4的高度比當前idx = stk.top() = 3的高度要小, 則可以知道右邊第一個高度< height[3]的位置是idx = 4- 此時我們想知道左邊第一個
< height[3]的位置為何, 因此我們先將當前的stk.top()給 pop 掉, 此時stk = [1], 然後取出stk.top() = 1為左邊第一個< height[3]的位置, 因為stk是遞增的, 所以將自己 pop 掉後的stk.top()必為左邊第一個比當前高度小的- 得到左、右邊第一個
< heights[stk.top()]的位置後, 即可計算idx = stk.top()的面積還要考慮 edge case 的情況:
- 因為我們在取完當前
stk.top()後將其 pop 掉後, 又取了一次stk.top()。若heights.size() = 1, 則stk.size() = 1會導致第二次取stk.top()時會出錯, 因此我們一定要有一個最低點在heights的起點, 這樣才能確保stk.size() > 1- 除此之外, 我們還要保證 while loop 定會被執行, 因此我們一定要有一個最低點在
heights的終點。否則, 當heights為遞增的, e.g.heights = [2, 4], 則 while loop 的條件heights[stk.top()] > heights[i]永遠不會成立, 會導致res不會被計算到
class Solution { |
- time:$O(n)$ ➔ for loop
- space:$O(n)$ ➔ stack 中的元素個數不超過
n
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論
