LeetCode - 84. Largest Rectangle in Histogram

Largest Rectangle in Histogram

Brute Force
计算每两个index之间的rectangle O(n^2)
Python TLE

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n = len(heights)
        res = 0
        for i in range(n):
            minV = heights[i]
            for j in range(i, n):
                minV = min(minV, heights[j])
                res = max(minV*(j-i+1), res)
        return res

解法一 brute force + pruning optimize

如何pruning?
只遍历局部峰值。什么是局部峰值?下一个index高度没有现在的高,就是局部峰值了。
For example, [2,1,5,6,4,3] -> 2, 6, 4在这里都是局部峰值。
为什么可以这样?
如果下一个index高度比现在高,现在可以组成的长方形,可以包括在下一个index里。
1, 5, 6为升序,我们可以省略1, 5
1 - (2, 1)形成的长方形可以包括在(2,1,5,6)里
5 - (1, 5) 形成的长方形可以包括在(1, 5, 6)里
     (2, 1, 5)形成的长方形可以包括在(2,1,5,6)里

Python

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n = len(heights)
        res = 0
        for i in range(n):
            if i+1<n and heights[i+1]>=heights[i]: continue
            minV = heights[i]
            for j in range(i, -1, -1):
                minV = min(minV, heights[j])
                res = max(res, minV*(i-j+1))
        return res

C++

class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        int maxV = 0;
        for(int i =0; i< height.size(); i++){
            if(i+1 < height.size()&& height[i] <= height[i+1])
                continue;
            int minV = height[i];
            for(int j =i; j>=0; j--){
                minV = min(minV, height[j]);
                int area = minV*(i-j+1);
                maxV = max(maxV, area);
            }
            
        }
        return maxV;
    }
};

解法二 DP

基本思想是找到以每一个index高度为高的最大rectangle。遍历每一位,寻找每一位的最左和最右边界。

Python

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        if not heights: return 0
        n = len(heights)
        leftLess = [0]*n
        leftLess[0] = -1
        for i in range(1, n):
            p = i-1
            while p>=0 and heights[p]>=heights[i]:
                p = leftLess[p]
            leftLess[i] = p
        rightLess = [0]*n
        rightLess[n-1] = n
        for j in range(n-2, -1, -1):
            p = j+1
            while p<n and heights[p]>=heights[j]:
                p = rightLess[p]
            rightLess[j] = p
        res = 0
        for i in range(n):
            res = max(res, heights[i]*(rightLess[i]-leftLess[i]-1))
        return res

C++

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if(heights.empty()) return 0;
        int n = heights.size(), res=0;
        int lessFromLeft[n] = {0};
        int lessFromRight[n] = {0};
        lessFromLeft[0] = -1;
        lessFromRight[n-1] = n;
        for(int i=1;i<n;i++){
            int p = i-1;
            while(p>=0 && heights[p]>=heights[i]){
                 p = lessFromLeft[p];
            }
            lessFromLeft[i] = p;
        }
        for(int i=n-2;i>=0;i--){
             int p = i+1;
            while(p<n && heights[p]>=heights[i]){
                p = lessFromRight[p];
            }
            lessFromRight[i] = p;
        }
        for(int i=0;i<n;i++){
            res = max(res, heights[i]*(lessFromRight[i]-lessFromLeft[i]-1));
        }
        return res;
    }
};

Similar Question:
LeetCode - 238. Product of Array Except Self

解法三 Stack

方法和上面相同,只不过通过stack来实现

Python

class Solution(object):
    def largestRectangleArea(self, heights):
        """
        :type heights: List[int]
        :rtype: int
        """
        heights.append(0)
        stack = [-1]
        res = 0
        for i in range(len(heights)):
            while heights[i]<heights[stack[-1]]:
                h = heights[stack.pop()]
                w = i-stack[-1]-1
                res = max(res, h*w)
            stack.append(i)
        return res
                

C++

class Solution {
public:
    int largestRectangleArea(vector<int> &height) {
        int res = 0;
        stack<int> st;
        height.push_back(0);
        for (int i = 0; i < height.size(); ++i) {
            if (st.empty() || height[st.top()] < height[i]) {
                st.push(i);
            } else {
                int cur = st.top(); st.pop();
                res = max(res, height[cur] * (st.empty() ? i : (i - st.top() - 1)));
                --i;
            }     
        }
        return res;
    }
};

Similar Question:
LeetCode - 739. Daily Temperatures​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值