力扣-单调栈-84 柱状图中最大的矩形

思路和时间复杂度

  1. 思路:利用单调栈找到比当前元素小的第一个元素,此时在栈中的元素顺序从栈头到栈底是递降的,然后栈顶元素的下一个元素,就是比当前元素小的前一个元素,这样计算以当前元素(栈顶)作为高的矩形有多大即可。
  2. 时间复杂度: O(n)      

代码

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.insert(heights.begin(), 0);
        heights.push_back(0);
        stack<int> st;
        st.push(0);

        int res = 0;
        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{
                // 栈口元素找到右侧第一个比栈口元素小的i
                while(!st.empty() && heights[i] < heights[st.top()]){
                    int mid = st.top();
                    st.pop();
                    if(!st.empty()){
                        int left = st.top();
                        res = max(res, heights[mid] * (i - left - 1));
                    }
                }
                st.push(i);
            }
        }
        return res;
    }
};

### 关于洛谷平台上的单调栈最大矩形问题 在洛谷平台上,涉及单调栈最大矩形面积的问题通常围绕如何高效计算二维网格中的最大全零子矩阵或最大全一子矩阵展开。这类题目可以通过将二维问题转化为一系列的一维问题来解决。 #### 1. **核心思想** 通过逐层扫描二维数组并将其高度映射为一维直方图的高度列表,可以将原问题简化为多个类似于力扣84题的“柱状图最大矩形”问题[^2]。具体来说: - 对每一行作为底边处理时,维护一个记录当前列连续未破坏地块数量(即高度)的数组 `height[]`。 - 利用前缀和的思想更新该数组:如果当前位置是可用地块,则对应高度加一;如果是不可用地块,则重置为零。 - 调用一次针对上述构建好的 `height[]` 的单调栈算法以获取基于这一特定底部的最大可能矩形面积。 这种方法的时间复杂度接近 O(n * m),其中 n 是行数而 m 是列数,因为每次都需要重新评估整个宽度方向上各点的状态变化情况[^1]。 #### 2. **单调栈的应用细节** 为了快速定位某个固定起点右侧最近的小于它的元素位置关系,采用递增形式存储索引值而非实际数值本身进入数据结构内部管理逻辑之中。当遇到新的更低条目准备加入队列顶端之前会持续弹出那些已经不可能成为候选解答组成部分的所有先前成员直到满足条件为止[^3]。 以下是具体的伪代码实现方式: ```cpp #include <bits/stdc++..h> using namespace std; int main(){ int n,m; cin>>n>>m; //读入尺寸大小 vector<vector<int>> grid(n,vector<int>(m)); for(auto &row :grid){ for(auto &cell: row){ char c; cin >>c ; cell=(c=='.'?1:0); //假设'.'代表可用土地,'#'代表损坏的土地 } } long maxArea=0; vector<int> heights(m,0); for(int i=0;i<n;++i){ stack<pair<int,int>> st;//pair<index,height> for(int j=0;j<m;j++){ if(grid[i][j]==1) ++heights[j]; else heights[j]=0; while(!st.empty() && st.top().second >=heights[j]){ auto [lastIndex,lastHeight]=st.top();st.pop(); int width = (st.empty()?j:(j-st.top().first-1)); maxArea=max(maxArea,(long)(width*lastHeight)); } st.emplace(j,heights[j]); } while(!st.empty()){ auto[lastIndex,lastHeight]=st.top();st.pop(); int width =(st.empty()?m:(m-st.top().first-1)); maxArea=max(maxArea,(long)(width*lastHeight)); } } cout<<maxArea<<"\n"; } ``` ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值