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

31 阅读3分钟
这道题描述的是小S最近在分析一个数组h1h2h3...hN,数组的每一个元素代表某种高度。小S对相和谐高度感兴趣的是,当我们选取任意k个相邻元素时,如何计算他们所能形成的最大矩形面积。对于k个相邻的元素,我们定义其矩形的最大面积为R(k)=k*min(h[i],h[i+1],...,h[i+k-1])即,R(k)的值为k个相邻元素中的最小值乘以k。现在小S希望能帮它找出对于任意k,R(k)的最大值。这道题考察了滑动窗口,最小值的计算,动态规划,时间复杂度分析和数组操作。
解题思路:我们需要计算一个数组中任意长度为k的子数所能形成的最大矩形面积。对于每个长度为k的子数组,矩形的面积等于子数组中最小高度乘以k。数组用于存储输入的高度数据,滑动窗口用于遍历所有可能的子数组。首先我们要遍历所有可能的窗口大小k,从k=1到k=n(数组长度);接着对于每个窗口大小k,遍历所有可能的窗口位置,从数组第一个元素开始,逐步滑动窗口,直到窗口的右边界到达数组的最后一个元素;接着计算每一个窗口的最小高度,在当前窗口找到最小的高度值;然后计算当前窗口的矩形面积,矩形面积等于最小高度乘以窗口大小k;最后更新最大面积,如果当前窗口的矩形面积大于之前记录的最大面积,则更新最大面积。我们也可以优化一下思路,当前代码的时间复杂度为O(n^3),因为对于每个窗口大小k,我们需要遍历所有可能的窗口位置,并在每个窗口中找到最小值,首先我们可以用单调栈,使用单调栈可以在O(n)的时间内计算出每个元素作为最小值时,两边能扩展的最大范围,从而计算出每个元素为最小值时的最大矩形面积;我们也可以用动态规划,通过动态规划记录每个位置作为窗口起始点的最小值,从而减少重复计算。
难点分析:滑动窗口的实现(滑动窗口的概念和窗口的滑动),最小值的计算(最小值的查找和优化最小值的查找),时间复杂度,边界条件的处理和测试用例的覆盖。
以下为该题代码:
    public static int solution(int n, int[] array) {
        int maxArea = 0;
        for (int k = 1; k <= n; k++) {
            int currentMin;
            for (int i = 0; i <= n - k; i++) {
                currentMin = array[i];
                for (int j = i; j < i + k; j++) {
                    currentMin = Math.min(currentMin, array[j]);
                }
                maxArea = Math.max(maxArea, currentMin * k);
            }
        }
        return maxArea;
    }
    public static void main(String[] args) {
        System.out.println(solution(5, new int[]{1, 2, 3, 4, 5}) == 9);  // 输出 true
        System.out.println(solution(6, new int[]{5, 4, 3, 2, 1, 6}) == 9);  // 输出 true
        System.out.println(solution(4, new int[]{4, 4, 4, 4}) == 16);  // 输出 true
    }
}