伴学笔记:矩形最大面积问题

141 阅读4分钟

伴学笔记:矩形最大面积问题

1. 问题分析

题目要求我们在给定的数组中,找出任意 k 个相邻元素所能形成的最大矩形面积。矩形面积的定义为:

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

即,我们需要计算所有长度为 k 的子数组的矩形面积,面积计算为该子数组的最小值乘以子数组的长度 k。我们的目标是找到一个 k,使得矩形面积最大。

2. 解决思路

为了求解该问题,我们可以考虑暴力枚举的方式,即:

  1. 对于每个可能的子数组长度 k(从 1nn 为数组的长度),我们计算该长度的子数组的矩形面积。
  2. 计算矩形面积时,首先需要找到该子数组中的最小值,然后计算面积。
  3. 通过滑动窗口,我们可以遍历所有可能的子数组长度,计算出矩形面积并更新最大面积。

3. 暴力法实现

为了实现这个思路,我们可以通过以下步骤:

  1. 外层循环:遍历所有可能的 k,即子数组的长度。
  2. 内层循环:对于每个 k,我们遍历所有长度为 k 的子数组。
  3. 计算矩形面积:对于每个子数组,找到其中的最小值,并乘以该子数组的长度,得到矩形面积。
  4. 更新最大矩形面积:在每次计算新的矩形面积时,更新最大面积。

4. 代码实现

def solution(n, array):
    max_area = 0
    
    # 对于每个长度 k 从 1 到 n
    for k in range(1, n+1):
        # 遍历所有长度为 k 的子数组
        for i in range(n - k + 1):
            # 计算当前窗口的最小值
            min_height = min(array[i:i+k])
            # 计算矩形面积
            area = k * min_height
            # 更新最大面积
            max_area = max(max_area, area)
    
    return max_area

if __name__ == "__main__":
    # 测试样例
    print(solution(5, [1, 2, 3, 4, 5]) == 9)  # 输出 9
    print(solution(6, [5, 4, 3, 2, 1, 6]) == 9)  # 输出 9
    print(solution(4, [4, 4, 4, 4]) == 16)  # 输出 16

5. 代码解析

  1. solution(n, array):该函数接受数组长度 n 和数组 array 作为输入,返回能够形成的最大矩形面积。
  2. max_area:用于记录当前计算出的最大矩形面积,初始值为 0。
  3. 外层循环 for k in range(1, n+1):循环从 1n,表示计算所有可能的矩形宽度。
  4. 内层循环 for i in range(n - k + 1):遍历所有长度为 k 的子数组。
  5. min(array[i:i+k]):计算当前子数组的最小值,用来求得矩形的高度。
  6. k * min_height:计算当前子数组的矩形面积。
  7. max(max_area, area):更新当前的最大面积。

6. 时间复杂度

时间复杂度为 O(n^2),这是因为:

  • 外层循环遍历每个可能的子数组长度 k,总共运行 n 次。
  • 内层循环遍历长度为 k 的所有子数组,总共运行 n - k + 1 次。
  • 对于每个子数组,我们计算最小值的时间复杂度是 O(k),因此总的时间复杂度为:

[ O(n^2) ]

在最坏情况下,n 很大时,暴力法的时间复杂度可能会较高,但对于小规模数据,暴力法是一个直观且容易实现的方案。

7. 测试用例

  1. 测试样例 1

    • 输入:n = 5, array = [1, 2, 3, 4, 5]
    • 输出:9
    • 解释:对于 k = 3,从 [3, 4, 5] 这个子数组,最小值是 3,矩形面积是 3 * 3 = 9。
  2. 测试样例 2

    • 输入:n = 6, array = [5, 4, 3, 2, 1, 6]
    • 输出:9
    • 解释:对于 k = 2,从 [5, 4] 这个子数组,最小值是 4,矩形面积是 2 * 4 = 8;而从 [1, 6] 这个子数组,最小值是 1,矩形面积是 2 * 1 = 2。最终最大矩形面积为 9。
  3. 测试样例 3

    • 输入:n = 4, array = [4, 4, 4, 4]
    • 输出:16
    • 解释:对于任何 k,矩形面积都将是 4 * k,因此最大面积为 16。

8. 优化建议

尽管暴力法直接有效,但在数组规模较大时,可能会有性能瓶颈。为了优化,可以考虑使用栈来维护有效的矩形高度,从而更高效地计算每个子数组的最小值和矩形面积。这个优化方法称为 单调栈法,它能将时间复杂度降低至 O(n)

9. 个人收获与感悟

通过这道题目,我加深了对暴力法的理解,尤其是在数组和矩阵类问题中,如何通过简单的循环进行逐步优化。此外,这个问题的解法也让我认识到滑动窗口和栈的组合应用,后续我可以用栈来优化解决方案,提高效率。

虽然暴力法的时间复杂度较高,但它很容易实现,尤其适合小规模数据。如果要处理大数据规模,优化算法是必不可少的。