最大矩形面积问题 | 豆包MarsCode AI刷题

30 阅读3分钟

题目描述

给定一个包含 N 个元素的数组 array,每个元素代表高度,数组中的元素分别为 h1, h2, ..., hn。对于 k 个相邻的元素,我们定义它的最大面积如下:

R(k) = k * min(h[i], h[i+1], ..., h[i+k-1])

需要找到 R(k) 的最大值,其中 k 是任意的合法长度。也就是说,我们希望找到一段连续子数组,使得这段子数组的最小高度乘以它的宽度最大。

例子

  • 输入:数组 [1, 2, 3, 4, 5]
  • 输出:9,因为面积最大的矩形是 [3, 4, 5],面积为 3 * 3 = 9

问题分析

这个问题可以归类为 最大矩形面积 的问题。需要找到一个连续子数组,使其面积最大。该面积由子数组的长度乘以子数组中的最小高度得到。

解决思路

我们可以使用 动态规划 来解决这个问题。动态规划的思想在于通过记录之前的计算结果,来推导后续的结果,从而避免重复计算。

  • dp[i] 表示以位置 i 结尾的最大面积。
  • 遍历数组,对每个位置 i,我们尝试找到以该位置结尾的连续子数组的最大面积。
  • 对于每一个新的位置 i,向左遍历,记录当前的最小高度 minHeight,然后计算面积并更新最大值。

通过以上思路,我们能够在一次遍历的过程中,找到以每个位置为结尾的最大矩形面积,并在过程中不断更新全局的最大面积。

动态规划实现过程

  1. 初始化 dp 数组用于存储以每个位置结尾的最大面积。
  2. 使用双重循环,外层循环遍历每个元素作为结尾,内层循环向左遍历找到最小高度。
  3. 通过 Math.min() 更新最小高度,计算当前面积,并通过 Math.max() 更新最大面积。

以下是 Java 代码的实现:

public class Main {
    public static int solution(int n, int[] array) {
        if (n == 0 || array == null || array.length == 0) {
            return 0;
        }
​
        int[] dp = new int[n];
        int maxArea = 0;
​
        for (int i = 0; i < n; i++) {
            int minHeight = array[i];
            dp[i] = array[i];
            maxArea = Math.max(maxArea, dp[i]);
​
            for (int j = i - 1; j >= 0; j--) {
                minHeight = Math.min(minHeight, array[j]);
                dp[j] = minHeight * (i - j + 1);
                maxArea = Math.max(maxArea, dp[j]);
            }
        }
​
        return maxArea;
    }
​
    public static void main(String[] args) {
        System.out.println(solution(5, new int[] { 1, 2, 3, 4, 5 }) == 9);
        System.out.println(solution(6, new int[] { 6, 2, 5, 4, 5, 1, 6 }) == 12);
        System.out.println(solution(4, new int[] { 1, 1, 1, 1 }) == 4);
        System.out.println(solution(0, new int[] {}) == 0);
        System.out.println(solution(3, new int[] { 2, 4, 2 }) == 6);
    }
}

代码解析

  • 边界检查:如果数组为空或者长度为 0,直接返回 0

  • 动态规划数组 **dp**:用于存储以每个位置结尾的最大面积。

  • 双重循环

    • 外层循环遍历每个元素 i
    • 内层循环从位置 i 向左遍历,通过不断更新 minHeight 来计算面积。
  • 最大面积更新:使用 maxArea 变量来持续记录遇到的最大面积。

时间复杂度分析

该算法的时间复杂度为 O(n^2) ,因为对于每个元素 i,我们可能需要遍历之前的所有元素来更新最小高度。这使得在最坏情况下,需要进行 n * (n - 1) / 2 次比较。

尽管时间复杂度相对较高,但这种实现方法简单明了,便于理解。在数据规模不大的情况下可以有效使用。

总结

通过这道题目,我们学习了如何通过动态规划来解决最大矩形面积问题。核心思想是找到每个位置结尾的最大面积,并在过程中不断更新全局最大值。动态规划的方法虽然可能在时间复杂度上不够最优,但其简洁性和可理解性使其非常适合用于理解问题的求解过程。