青训营X豆包MarsCode 技术训练营第一课 AI刷题16:最大矩形面积问题| 豆包MarsCode AI 刷题

81 阅读2分钟

问题描述

image.png


测试样例

样例1:

输入:n = 5, array = [1, 2, 3, 4, 5]
输出:9

样例2:

输入:n = 6, array = [5, 4, 3, 2, 1, 6]
输出:9

样例3:

输入:n = 4, array = [4, 4, 4, 4]
输出:16

  1. 其实,这一题就是找数组的最大相同部分,也就是说尽可能的找到各个柱子凑在一起,找出最大的共有部分。

  2. 当然,如果其中一个柱子很高,而其他柱子很矮,那也有可能最大面积就取那个很高的柱子

  3. 很显然,这一题跟柱子的高度以及所有柱子的共有部分有关。典型的单调栈结构

  4. 既然是单调栈,那就假设没根柱子的高度是最大值,然后找左侧、右侧离当前柱子的最近距离。中间就是共有性质。

cppCopy Code
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int solution(int n, int array[]) {
    // 创建一个单调递增的栈
    stack<int> s;
    int maxArea = 0;
    
    // 遍历所有的柱子
    for (int i = 0; i < n; ++i) {
        // 如果当前柱子比栈顶柱子低,则计算栈顶柱子的矩形面积
        while (!s.empty() && array[s.top()] > array[i]) {
            int h = array[s.top()];
            s.pop();
            int w = s.empty() ? i : i - s.top() - 1;
            maxArea = max(maxArea, h * w);
        }
        // 将当前柱子的索引入栈
        s.push(i);
    }

    // 处理栈中剩余的柱子
    while (!s.empty()) {
        int h = array[s.top()];
        s.pop();
        int w = s.empty() ? n : n - s.top() - 1;
        maxArea = max(maxArea, h * w);
    }

    return maxArea;
}

算法思路

  1. 使用栈来追踪柱子的索引

    • 栈用于追踪当前直方图中柱子的索引,保证栈中的柱子高度是递增的。
    • 对于每个柱子(array[i]),我们不断弹出栈中的柱子,直到栈顶柱子的高度小于当前柱子的高度。每次弹出一个柱子时,我们可以计算以该柱子为高的矩形面积。
  2. 计算最大矩形面积

    • 每次弹出栈顶元素时,假设该元素为矩形的高度,矩形的宽度为从该柱子到当前柱子之前的柱子之间的距离。
    • 通过不断更新面积,最终找到最大的矩形。
  3. 处理栈中剩余的柱子

    • 在遍历所有柱子后,栈中仍可能有柱子,这些柱子表示高度还可以延续到数组的末尾,因此需要继续计算它们的最大面积。

时间和空间复杂度

  • 时间复杂度O(n)。每个柱子至多入栈和出栈一次,因此时间复杂度是线性的。
  • 空间复杂度O(n)。栈最多存储 n 个元素(即柱子的索引)。
  • 以上就是我的该题解决策略。