【力扣练习记录】84.柱状图中最大的矩形

这篇博客探讨了一种常见的算法问题——在给定柱状图中找到能够勾勒的最大矩形面积。作者首先尝试了使用双重循环的简单方法,但发现这种方法在处理大规模数据时会导致超时。接着,作者学习并介绍了使用单调栈来优化解决方案,虽然对这种方法的理解还不够深入。单调栈能够有效地减少计算复杂性,避免了不必要的遍历,从而提高了算法效率。
摘要由CSDN通过智能技术生成

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

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

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
示例:

输入: [2,1,5,6,2,3]
输出: 10
当时想着就这?还困难?随便就想出来了
结果很不幸没有通过全部测试案例
因为超时了
然后一看案例,魔鬼啊
先粘贴一下小白的代码,毕竟用了双重循环,其实就是枚举高和宽,还搞得像dp:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
//根据以往经验,如果是判断以每个矩形为右边然后和左边组成的最大矩形面积呢
       int dp[heights.size()];
       dp[0]=heights[0];
       int result=dp[0];
       for(int i=1;i<heights.size();i++){
          int maxarea=0;
          int minheight=heights[i];
          dp[i]=heights[i];
          for(int j=i-1;j>=0;j--){
             minheight=min(minheight,heights[j]);
             int area=minheight*(i-j+1);
             dp[i]=max(dp[i],area);   
          }
          result=max(result,dp[i]);
       }
       return result;
    }
};

然后看了教程
原来是用单调栈。。。
好好学习一下,虽然理解没那么透彻……

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        // 初始化最终结果为0
        int res = 0;
        stack<int>st;

        // 将给定的原数组左右各添加一个元素0
        int newHeights[heights.size()+2];
        newHeights[0] = 0;
        newHeights[heights.size()+1] = 0;
        for (int i = 1; i < heights.size()+ 1; i++) {
            newHeights[i] = heights[i - 1];
        }

        // 开始遍历
        for (int i = 0;i<heights.size()+2; i++) {
            // 如果栈不为空且当前考察的元素值小于栈顶元素值,
            // 则表示以栈顶元素值为高的矩形面积可以确定
            while (!st.empty() && newHeights[i] < newHeights[st.top()]) {
                // 弹出栈顶元素
                int cur=st.top();
                st.pop();
                // 获取栈顶元素对应的高
                int curHeight = newHeights[cur];

                // 栈顶元素弹出后,新的栈顶元素就是其左侧边界
                int leftIndex = st.top();
                // 右侧边界是当前考察的索引
                int rightIndex = i;
                // 计算矩形宽度
                int curWidth = rightIndex - leftIndex - 1;

                // 计算面积
                //cout<<curWidth<<" "<<curHeight<<endl;
                res =max(res, curWidth * curHeight);
            }
            
            // 当前考察索引入栈
            st.push(i);
        }

        return res;
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值