84. 柱狀圖中最大的矩形

ouyangxx發表於2024-11-11
  1. 題目連結

  2. 解題思路:

    • 題目乍一看沒有思路,那我們來想一想如果暴力求解怎麼辦。最大的矩形,他總有一個高(豎著的),然後有一個寬(橫著的),那我們就暴力求解每一個高,也就是每一個下標i,對應的heights[i],最大的寬是多少,然後求出所有的解後,最優的便是結果。
    • 怎麼求解以heights[i]為高,最大的寬是多少?用單調棧。單調棧是啥?簡單來說就是,求i左邊,比i「小的,離i最近的」在哪,求i右邊,比i「小的,離i最近的」在哪。(當然,也可以求大的)
    • 所以,我們就可以得到以heights[i]為高,然後得出最大的寬,這就是其中之一的結果。把所有結果得到之後,求最大的那個,就是最終的結果。
  3. 程式碼

    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            stack<int> st;    // 棧底到棧頂是小到大   存的是下標
            int ans = 0;
            int n = heights.size();
            for (int i = 0; i < n; ++i) {
                while(!st.empty() && heights[i] < heights[st.top()]) {
                    int wid_right = i;    // 寬的右邊界
                    int wid_left = 0;   // 寬的左邊界
                    int height = heights[st.top()];   // 高
                    st.pop();
                    if (!st.empty()) {    // 如果棧不為空  它下面壓著的  就是左邊 比他小 離他最近的
                        wid_left = st.top() + 1;
                    }
                    ans = max(ans, (wid_right - wid_left) * height);
                }
                st.push(i);
            }
            // 棧不空
            while(!st.empty()) {
                int wid_right = n;    // 寬的右邊界  右邊沒有比當前棧頂小的了
                int wid_left = 0;    // 寬的左邊界
                int height = heights[st.top()];
                st.pop();
                if (!st.empty()) {
                    wid_left = st.top() + 1;
                }
                ans = max(ans, (wid_right - wid_left) * height);
            }
            return ans;
        }
    };
    

相關文章