单调栈2 - 矩形最大面积

本文介绍了一种算法,用于在一个n*m的棋盘中找到最大的全由红色方格组成的矩形区域。通过将二维问题转化为一维高度数组,利用栈来计算每个位置可能的最大矩形面积,最终得到整个棋盘上的最大红色矩形面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    这道题的唯一的难点是:二维转化成一维的时候:

 /* 如果当前行 j 位仍然是1,那么height[j]++。否则height[j]更新为0 */

   比如第一列上一行是 '.', 第二行第一列是 'X',那肯定无法形成矩形。

问题描述

有一个 n*m 的棋盘,棋盘上的每个点都是红的绿的。

你需要找出一个面积最大的矩形区域,使得其中没有绿的格子。

输入格式

第一行 2 个正整数 n,m,描述棋盘尺寸。

接下来 n 行描述这个棋盘,每行 m 个字符,每个字符为 . 或 X,其中 . 表示这个位置是红色的,X 表示这个位置是绿色的。

输出格式

一行一个整数,表示最大面积。

样例输入

4 5
.....
XXXXX
.X...
.....

样例输出

6

样例解释

以第 3 行第 3 列的方格为左上角,第 4 行第 5 列的方格为右下角的矩形区域是全红的矩形中面积最大的。

数据范围

对于 30% 的数据,n,m<=100;

对于 60% 的数据,n,m<=400;

对于 85% 的数据,n,m<=1,000;

对于 100% 的数据,n,m<=1,500。

#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int getAnswerInRow (int n, int *height);
int getAnswer(int n, int m, string *matrix);

int getAnswer(int n, int m, string *matrix) {
    /* 如果当前行 j 位仍然是1,那么height[j]++。否则height[j]更新为0 */
    int maxrect = 0;
    int *height = new int[m+2];
    for(int i = 0; i < m+2; i++)
        height[i] = 0;
    for(int i = 0; i < n; i++){
        for( int j = 0; j < m; j++){
            if(matrix[i][j] == 'X')
                height[j+1] = 0;   /*因为下个函数从1开始*/
            else
                height[j+1]++;
        }
        maxrect = max(maxrect, getAnswerInRow(m,height));
    }
    return maxrect;
    
}
int getAnswerInRow (int n, int *height) {
    int ans = 0;
    stack< int > myStack;
    /* push(0) 是第一个哨兵 */
    myStack.push(0);
    /* N+1 是最后一个哨兵 */
    for(int i = 1; i <= n+1; ++i){
        while ((height[myStack.top()] > height[i])) {
            int nowHeight = height[myStack.top()];
            myStack.pop();
            ans = max(ans, nowHeight * (i - myStack.top() - 1));
            /* 其实蛮不容易的QAQ,我这一句一直写错,后来重新看了一遍视频才写出来- - */
        }
        myStack.push(i);
    }
    return ans;
    /* 请在这里设计你的算法,并将答案返回 */
}

int main() {
    ios::sync_with_stdio(false);  // 读入优化
    
    int n, m;
    cin >> n >> m;
    
    string *matrix = new string[n]();
    
    for (int i = 0; i < n; ++i)
        cin >> matrix[i];
    
    cout << getAnswer(n, m, matrix) << endl;
    
    delete[] matrix;
    return 0;
}

### 单调栈算法求解最大矩形问题的实现 单调栈是一种经典的数据结构,可以高效地解决许多与数组或列表中元素顺序相关的问题。在柱状图中寻找最大矩形面积问题中,单调栈被广泛使用以降低时间复杂度。以下是一个完整的实现过程和解释。 #### 1. 算法的核心思想 为了找到柱状图中的最大矩形面积,需要遍历每个柱子,并计算以该柱子为高度的最大矩形面积。通过维护一个单调递增,可以快速确定每个柱子左右两侧第一个比它矮的柱子的位置,从而计算出宽度并得到面积[^4]。 #### 2. 实现代码 以下是基于单调栈C++ 实现: ```cpp class Solution { public: int largestRectangleArea(vector<int>& heights) { stack<int> s; // 单调递增 heights.push_back(0); // 添加哨兵元素,确保最终会被清空 int n = heights.size(); int ans = 0; for (int i = 0; i < n; ++i) { // 当前高度小于顶高度时,处理顶元素 while (!s.empty() && heights[i] < heights[s.top()]) { int h = heights[s.top()]; // 顶元素的高度 s.pop(); // 弹出顶元素 int w = s.empty() ? i : i - s.top() - 1; // 计算宽度 ans = max(ans, h * w); // 更新最大面积 } s.push(i); // 将当前索引入 } return ans; } }; ``` #### 3. 代码解析 - **初始化**:使用一个 `s` 来存储柱子的索引。内的索引对应的柱子高度是单调递增的。 - **添加哨兵元素**:在输入数组末尾添加一个高度为 0 的柱子,确保所有柱子都会被弹出进行处理[^5]。 - **遍历柱子**: - 如果当前柱子的高度大于等于顶柱子的高度,则将当前柱子的索引入- 如果当前柱子的高度小于顶柱子的高度,则开始计算以顶柱子为高度的最大矩形面积- **计算宽度**:当从中弹出一个柱子时,其左侧第一个比它矮的柱子是顶的下一个柱子,右侧第一个比它矮的柱子是当前柱子。根据这两个位置可以计算出宽度。 - **更新最大面积**:每次计算出一个新的矩形面积后,与当前最大面积比较并更新。 #### 4. 时间复杂度分析 - 每个柱子最多入一次、出一次,因此时间复杂度为 O(n),其中 n 是柱子的数量[^3]。 #### 5. 示例 假设输入柱状图的高度为 `[2, 1, 5, 6, 2, 3]`,按照上述算法可以逐步计算出最大矩形面积为 10。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值