LeetCode 84. 柱状图中最大的矩形 | C语言版

文章提供了两种解决LeetCode84问题的方法,一种是使用单调栈,详细解释了如何通过栈来找到每个柱子左右两侧较小的柱子以计算最大矩形面积;另一种方法减少了遍历的节点数,但未给出具体代码实现。通过这两种策略,可以有效地求解柱状图中能形成的最大矩形面积。
摘要由CSDN通过智能技术生成

LeetCode 84. 柱状图中最大的矩形

题目描述

题目地址84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

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

在这里插入图片描述

解题思路

思路一:使用栈
代码实现
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        //42. 接雨水和 739. 每日温度 是找每个柱子左右两边第一个大于该柱子高度的柱子,单调栈从栈头到栈底的顺序是从小到大;而本题是找每个柱子左右两边第一个小于该柱子的柱子,单调栈从栈头到栈底的顺序是从大到小
        //什么是单调栈?单调栈就是保持栈内元素有序
        //单调栈使用情景?通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了
        //柱状图中的最大矩形:栈头元素就是中间的柱子,栈头第二个元素就是左边的小柱子(比中间柱子小得柱子),而添加的元素就是右边的小柱子。栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度

        //单调栈
        stack<int> st;
        //数组头部加入元素0
        heights.insert(heights.begin(),0);
        //数组尾部加入元素0
        heights.push_back(0);
        st.push(0);
        int result=0;

        //第一个元素已经入栈,从下标1开始
        for(int i=1;i<heights.size();i++){
            //如果当前遍历的元素(柱子)高度大于栈顶元素(中间的柱子)的高度,就把这个元素加入栈中,因为栈里本来就要保持从大到小的顺序(从栈头到栈底)
            if(heights[i]>heights[st.top()]){
                st.push(i);
            }
            //如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。
            else if(heights[i]==heights[st.top()]){
                st.pop();
                st.push(i);
            }
            //如果当前遍历的元素(柱子)高度小于栈顶元素的高度,此时以最小柱子为标准,算柱状图中的最大矩形
            else{
                while(!st.empty() && heights[i]<heights[st.top()]){
                    //中间的柱子,下标为mid
                    int mid=st.top();
                    st.pop();
                    if(!st.empty()){
                        int left=st.top();
                        int right=i;
                        int w=right-left-1;
                        int h=heights[mid];
                        result=max(result,w*h);
                    }
                }
                st.push(i);
            }
        }
        return result;

    }
};
运行结果

在这里插入图片描述

参考文章:https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html#%E5%8D%95%E8%B0%83%E6%A0%88
思路二:减少遍历节点数
代码实现
在这里插入代码片
运行结果
参考文章:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李莲花*

多谢多谢,来自一名大学生的感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值