青训营X豆包MarsCode技术训练|豆包MarsCode AI 刷题

97 阅读3分钟

image.png

image.png

image.png 这个问题要求我们对于任意 k 个相邻的元素,计算它们所能形成的最大矩形面积。对于 k 个相邻元素,面积的计算公式是:

R(k)=k×min⁡(h[i],h[i+1],...,h[i+k−1])R(k)=k×min(h[i],h[i+1],...,h[i+k−1])

我们的任务是找到对于任意 kR(k) 的最大值。

思路分析

  1. 矩形面积的计算

    • 对于 k 个相邻元素,面积的计算公式是当前子数组中的最小值与 k 的乘积。
    • 为了计算所有可能的 k 的最大矩形面积,我们可以先计算每个长度为 k 的子数组中的最小值,再计算相应的矩形面积。
  2. 滑动窗口

    • 每次我们只需要更新窗口内的最小值。使用双端队列(deque)可以帮助我们在滑动窗口中高效地找到最小值。
    • 通过滑动窗口,我们可以在每个 k 长度的窗口中计算矩形面积,并更新最大值。

解决方案

  1. 滑动窗口:我们用一个滑动窗口来遍历所有的子数组,每次滑动时,我们只需要对窗口内的最小值进行更新。
  2. 队列优化:使用一个双端队列来维护当前窗口中的最小值,使得每次更新窗口时,最小值能够快速找到。

算法步骤

  1. 对于每个 k 从 1 到 n,我们使用滑动窗口的方法来计算每个窗口的最小值。

  2. 使用一个双端队列维护当前窗口中的最小值,以便在每次滑动时高效更新最小值。

  3. 对于每个 k,计算最大矩形面积,并更新最大值。

  4. 代码解释

  5. 滑动窗口计算

    • 对于每一个 k,我们遍历从第 0 到第 n-k 的所有窗口。
    • 在每个窗口内,我们使用双端队列来保持当前窗口内的最小值。队列的头部保存着最小值的索引。
  6. 双端队列维护最小值

    • 我们从左到右遍历数组,队列中的元素会按大小顺序排列。每次遇到比队尾元素小的值时,我们会弹出队尾的元素,直到队列中的所有元素都比当前值大或等于当前值。
    • 当滑动窗口右移时,我们需要移除队列中已经不在窗口范围内的元素。
  7. 计算最大面积

    • 对于每个窗口,计算当前窗口的最小值(即队列头部的值),然后计算矩形的面积,更新最大面积。

复杂度分析

  • 对于每个 k,滑动窗口遍历整个数组,时间复杂度为 O(n)。由于我们对每个 k 都执行一次这个操作,因此总时间复杂度为 O(n^2)
  • 双端队列的操作是 O(1),每个元素最多被加入和移除一次,因此对于每个 k,滑动窗口的操作时间是 O(n)

因此,总的时间复杂度为 O(n^2),适用于中小规模的输入。