代码随想录训练营第60天|84.柱状图最大的矩形

84.柱状图最大的矩形

对于柱状图最大的矩形,我们将用两种方法进行求解,其中暴力解法会超时,此处会给出解法,但是不可以解决改题目。

暴力解法

对于暴力解法,首先,我们可以遍历每一个位置,求出以每一个位置为高,它所能构成的最大矩形,对此,我们用从这个位置,利用左右指针进行遍历,求出可以构成的最大矩形的边界,然后求出这个面积。将这个面积与已经求出的最大面积进行比较,选择较大者即可。

代码

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
    int result=0;
    for(int ii=0;ii<heights.size();ii++)
    {
        int left = ii;
        int right = ii;
        for(;left>=0;left--)
        {
            if(heights[left]<heights[ii])
            break;
        }
        for(;right<heights.size();right++)
        {
            if(heights[right]<heights[ii])
            break;
        }
        result=max(result,(right-left-1)*heights[ii]);
    }
    return result;
    }
};

单调栈

这是一道经典的栈的应用题,称为柱状图中最大的矩形,其主要思路如下:

1.对于每个柱子,以其高度为矩形高,并向左右两侧扩展找到第一个小于其高度的柱子,计算以当前柱子为高的最大矩形面积。

2.找到所有以每个柱子为高的最大矩形面积中的最大值。

为了实现这个算法,我们需要使用单调递增栈来记录某个元素的左侧第一个小于它的元素位置,同时也需要使用单调递增栈来记录某个元素的右侧第一个小于它的元素位置。

具体来说,我们从左向右遍历每个柱子,如果当前柱子的高度大于等于栈顶元素的高度,则将当前柱子的下标入栈;否则,我们弹出栈顶元素并计算以该元素的高度为矩形高度的最大矩形面积,直到栈为空或者当前柱子的高度大于栈顶元素的高度。计算完以当前柱子为高度的矩形面积后,我们将当前柱子的下标入栈。

在计算完所有柱子左侧第一个小于其高度的元素位置后,我们再从右向左遍历每个柱子,使用类似的方法计算出每个柱子右侧第一个小于其高度的元素位置。在计算完所有柱子右侧第一个小于其高度的元素位置后,我们遍历所有柱子,计算以每个柱子为高度的最大矩形面积,并更新最大值即可。

代码

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        stack<int> st;
        vector<int> left(n), right(n);
        
        // 计算每个柱子左边第一个小于它的柱子的位置
        for (int i = 0; i < n; i++) {
            while (!st.empty() && heights[st.top()] >= heights[i]) {
                st.pop();
            }
            left[i] = st.empty() ? -1 : st.top();
            st.push(i);
        }
        
        // 清空栈,重新使用
        while (!st.empty()) st.pop();
        
        // 计算每个柱子右边第一个小于它的柱子的位置
        for (int i = n - 1; i >= 0; i--) {
            while (!st.empty() && heights[st.top()] >= heights[i]) {
                st.pop();
            }
            right[i] = st.empty() ? n : st.top();
            st.push(i);
        }
        
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans = max(ans, heights[i] * (right[i] - left[i] - 1));
        }
        return ans;
    }
};

你可能感兴趣的:(leetcode,算法,数据结构)