题目描述
给定一个数组 h[1], h[2], ..., h[N],其中每个元素代表某种高度。对于任意 k 个相邻的元素,我们需要计算它们所能形成的最大矩形面积。矩形面积的计算方式为:R(k) = k × min(h[i], h[i+1], ..., h[i+k-1]),即 k 个相邻元素中的最小值乘以 k。
思路分析
这个问题初看可能让人想到暴力解法,即对于每个 k,遍历所有可能的 k 个相邻元素,找到它们的最小值并计算面积。然而,这种方法的时间复杂度为 O(N^2 * K),对于较大的 N 和 K 来说显然是不可接受的。
一个更高效的方法是使用单调栈。单调栈是一种数据结构,可以在 O(N) 时间内找到数组中每个元素的左边和右边第一个比它小的元素的位置。利用这些信息,我们可以计算出以当前元素为最小高度的最大矩形面积。
单调栈是一种特殊的栈结构,它在普通的栈的“先进后出”的特性基础上,增加了一个条件:从栈顶到栈底的元素必须是单调递增或单调递减的。这种数据结构在解决一些特定的算法问题时非常有用,尤其是那些涉及到需要快速找到一个元素左边或右边第一个比它大或小的元素的问题。
然而,题目中的要求是对任意 k 计算最大面积,这看似与单调栈直接解决的问题有所不同。实际上,我们可以稍作变通:对于每个元素,我们可以考虑以其为最小高度的所有可能的矩形(即不同长度的矩形),然后从中选择面积最大的一个。
代码详解
-
初始化变量
max_area:记录当前找到的最大矩形面积。 -
遍历每个可能的矩形长度
k实际上,我们不需要显式地遍历
k,因为我们可以在单调栈的过程中同时考虑所有可能的k。 -
使用单调栈处理数组
遍历数组
array,对于每个元素,如果栈不为空且当前元素小于栈顶元素对应的高度,则弹出栈顶元素,并计算以该元素为最小高度的矩形的最大面积。面积的计算方式为:
height * width,其中height为弹出的栈顶元素对应的高度,width为当前位置与栈顶下一个元素位置之间的距离(如果栈为空,则距离为当前位置到数组末尾的距离)。 -
处理栈中剩余元素
遍历结束后,栈中可能还剩下一些元素,我们需要对它们进行同样的处理。
假设我们有一个高度数组 [2, 1, 4, 5, 3, 7],我们可以用以下步骤来找到最大矩形面积:
-
初始化一个空栈。
-
遍历数组,对于每个元素:
- 如果栈为空,或者当前元素大于栈顶元素(表示当前元素可以作为矩形的一边),则将当前元素索引入栈。
- 如果当前元素小于栈顶元素,说明当前元素结束了一个或多个矩形,我们需要计算这些矩形的面积,并更新最大面积。
- 弹出栈顶元素,并更新宽度(即弹出元素的索引与栈顶元素索引的差值加1),计算面积,并与当前最大面积比较。
- 重复上述过程,直到栈空或当前元素大于栈顶元素。