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

103 阅读4分钟

一、题目概述

  1. 题目背景

    • 题目涉及对一个数组的分析,数组中的每个元素代表某种高度。问题的核心是当选取任意k个相邻元素时,如何计算它们所能形成的最大矩形面积。

二、解题思路

  1. 算法选择 - 滑动窗口法

    • 原理

      • 滑动窗口方法适用于处理这种需要在数组上进行局部范围操作的问题。通过移动固定大小或可变大小的 “窗口” 来遍历数组,计算每个窗口内的相关值。
      • 在本题中,对于每个可能的k值(从 1 到数组长度k),我们可以把长度为k的子数组看作一个 “窗口”,在数组上滑动这个 “窗口”,计算每个窗口对应的矩形面积。
    • 步骤

      • 首先,需要对每个可能的值进行循环。这通过外层循环for k in range(1, n + 1)实现,其中n是数组的长度。
      • 对于每个值,需要在数组上滑动长度为的窗口。通过内层循环for i in range(n - k + 1)实现,这个循环用于确定窗口的起始位置。
      • 当确定了窗口的起始位置和长度()后,获取窗口内的子数组sub_array = array[i:i + k]
      • 计算子数组中的最小值min_height = min(sub_array),这是计算矩形面积的关键,因为矩形的高度取决于子数组中的最小高度。
      • 根据公式,计算当前窗口对应的矩形面积area = k * min_height
      • 在每次计算出矩形面积后,与当前记录的最大面积max_area进行比较。如果计算得到的面积area大于max_area,则更新max_area,即if area > max_area: max_area = area

三、代码实现

def solution(n, array):
    max_area = 0
    for k in range(1, n + 1):
        for i in range(n - k + 1):
            sub_array = array[i:i + k]
            min_height = min(sub_array)
            area = k * min_height
            if area > max_area:
                max_area = area
    return max_area
  • 变量解释

    • max_area:用于记录整个过程中计算得到的最大矩形面积,初始化为 0。
    • k:表示相邻元素的个数,在for k in range(1, n + 1)循环中遍历所有可能的值。
    • i:用于确定子数组(窗口)的起始位置,在for i in range(n - k + 1)循环中遍历所有可能的起始位置。
    • sub_array:表示当前窗口对应的子数组。
    • min_height:子数组中的最小高度,通过min(sub_array)计算得到。
    • area:根据公式计算得到的当前窗口对应的矩形面积。

四、算法复杂度分析

  1. 时间复杂度

    • 外层循环遍历k值,从 1 到n,时间复杂度为O(n)。

    • 对于每个k值,内层循环用于确定子数组的起始位置,循环次数为n-k+1。当k=1时,内层循环执行n次;当k=2时,内层循环执行n-1次;以此类推,当k=n时,内层循环执行 1 次。

    • 对于每个子数组,计算最小值min_height的时间复杂度在最坏情况下为O(k)(例如,当子数组是递减序列时)。

    • 总的时间复杂度可以通过对所有内层循环的操作次数进行求和得到:O(n^3)

  2. 空间复杂度

    • 除了存储输入数组和一些临时变量外,没有使用额外的数据结构来存储大量数据。
    • 函数中定义的变量max_areakimin_heightarea都只占用常数级别的空间。
    • 因此,空间复杂度为O(1),是一个常量空间复杂度。

五、测试用例

  1. 题目给定的测试样例

    • 样例 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
if __name__ == "__main__":
    assert solution(5, [1, 2, 3, 4, 5]) == 9
    assert solution(6, [5, 4, 3, 2, 1, 6]) == 9
    assert solution(4, [4, 4, 4, 4]) == 16
  • assert语句会检查solution函数的输出是否与预期的输出一致。如果不一致,会抛出AssertionError,帮助我们发现函数实现中的错误。

六、收获与总结

  1. 算法与数据结构层面:深入领悟滑动窗口算法,明晰设置窗口大小、移动规则及操作窗内元素的要点,像本题依k值定窗口大小遍历数组。复杂度分析能力进阶,从推导公式确认本题时间复杂度、空间复杂度,深知其关联算法性能,为优化算法筑牢思维根基。

  2. 编程实践维度:掌握嵌套循环遍历子数组及巧用内置函数(如min)简化计算的编码技巧,还学会用变量(max_area)管理结果、梳理逻辑。同时,领会assert语句做单元测试效用,借测试样例查错,保障代码可靠,利后续优化与回归测试。

  3. 问题解决思维角度:强化将抽象问题描述转化为具体解法的能力,从理解最大矩形面积定义到敲定滑动窗口方案,助我应对复杂问题时思路更清晰、有条理。