leetcode_力扣_84. 柱状图中最大的矩形

题目描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例

  • 示例 1:
    01
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
  • 示例 2:
    02
输入: heights = [2,4]
输出: 4

提示

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

解题思路

  • 当使用暴力解法时,会出现超时现象。
  • 使用单调栈,即栈内元素按非递减压入,每当碰到比栈顶元素小的元素时,进行出栈操作直至栈顶元素小于等于指定元素;
  • 在出栈的同时,进行面积的计算;
  • 对数组遍历结束后,若栈内元素不为空,再次进行出栈并计算面积。

代码

  • 单调栈
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {

        int v_len = heights.size();
        int *stk = new int[v_len];
        int area_max, stk_pos, area, left, right, i, h, temp, temp_pos;

        area_max = 0;
        stk_pos = 0;

        for(i = 0; i < v_len;){

            if(stk_pos == 0 || heights[i] >= heights[stk[stk_pos-1]]){
                if(heights[i] != 0){
                    stk[stk_pos++] = i;
                }
                i++;
                continue;
            }

            while(stk_pos > 0 && heights[i] < heights[stk[stk_pos-1]]){
                right = i;
                left = stk[stk_pos-1];
                h = heights[left];
                stk_pos--;
                temp_pos = left;
                temp = heights[left];
                while(left > 0 && heights[left-1] >= temp){
                    if(heights[temp_pos] == heights[left-1]){
                        stk_pos--;
                    }
                    left--;
                }
                // cout << left << " " << right << " " << h << endl;
                area = (right-left) * h;
                area_max = area_max > area ? area_max : area;
            }

        }

        while(stk_pos > 0){
            right = i;
            left = stk[stk_pos-1];
            h = heights[left];
            stk_pos--;
            temp_pos = left;
            temp = heights[left];
            while(left > 0 && heights[left-1] >= temp){
                if(heights[temp_pos] == heights[left-1]){
                    stk_pos--;
                }
                left--;
            }
            // cout << left << " " << right << " " << h << endl;
            area = (right-left) * h;
            area_max = area_max > area ? area_max : area;
        }

        return area_max;
    }
};
  • 暴力解法
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {

        int v_len = heights.size();
        int i, left, right, area, area_max;

        area_max = 0;

        for(i = 0; i < v_len; i++){
            left = right = i;
            while(left-1 >= 0 && heights[left-1] >= heights[i]){
                left--;
            }
            while(right+1 < v_len && heights[right+1] >= heights[i]){
                right++;
            }

            area = (right-left+1) * heights[i];
            // cout << area << endl;

            area_max = area_max > area ? area_max : area;
        }

        return area_max;
    }
};

提交结果

res

总结

  • 单调栈思想,可以用于方便的解决距离一个值最近但比其低或者高的问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值