1. 程式人生 > 其它 >js基礎_邏輯運算子

js基礎_邏輯運算子

題目描述:

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

 

 

輸入:heights = [2,1,5,6,2,3]
輸出:10
解釋:最大的矩形為圖中紅色區域,面積為 10

解題思路:

看題目本身,跟經典的接雨水有點類似。但不同點是接雨水的高度是由左右邊界的最小值決定,這題的高度則是由每個柱子本身決定。

1. 暴力解法:自己能想到的解法。由當前柱子向左右兩邊延伸,只要滿足高度大於當前柱子的,就能繼續延伸,直到遇到高度小於當前柱子或到達邊界。這實際上是以每個柱子為中心,向左右去尋找當前柱子的邊界,將邊界作為矩形寬度,柱子高度為矩形長度。最後取面積最大的矩形為最終結果。時間複雜度O(n^2),會超時。

 

2. 單調棧:大四演算法課上單獨講過這類演算法。實際是拿空間換時間,維護一個單調遞增的棧,一定程度上是保證了左邊界,再通過遍歷的方式尋找右邊界。始終維護一個單調遞增的棧,遇到小於棧頂元素高度的柱子,則需要將棧頂元素出棧,也就意味著對於當前棧頂的元素來說,找到了其左右邊界,左邊界就為棧的下一個元素(若不存在則邊界為-1),右邊界為當前遍歷到元素。當遍歷結束後,需要清空棧,此時的右邊界的確定的,為陣列的長度,需要確定的是左邊界,同樣為棧的下一個元素(若不存在則邊界為-1)。

 

程式碼:

解法一:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        int ans = 0;
        for(int i=0; i<n; i++) {
            int l = i;
            int r = i;
            while(l>=0 && heights[i] <= heights[l]) {
                l--;
            }
            while(r<n && heights[i] <= heights[r]) {
                r++;
            }
            if(r>=n)
                r = n-1;
            else if(r != i)
                r = r-1;
            
            if(l<0)
                l=0;
            else if(l != i)
                l = l+1;
            int area = heights[i]*(r-l+1);
            ans = max(ans, area);
        }
        return ans;
    }
};

  

解法二:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        stack<int> s;
        int ans = 0;
        for(int i=0; i<n; i++) {
            while(!s.empty() && heights[s.top()] > heights[i]) {
                int tmp = s.top();
                s.pop();
                int length = heights[tmp];
                int weight = i;
                if(!s.empty())
                    weight = i-s.top()-1;
                ans = max(ans, length*weight);
            }
            s.push(i);
        }
        
        int length = 0;
        int weight = n;
        while(!s.empty()) {
            int tmp = s.top();
            s.pop();
            length = heights[tmp];
            weight = n;
            if(!s.empty())
                weight = n-s.top()-1;
            ans = max(ans, length*weight);
        }
        
        return ans;
        
    }
};