日常刷题 | 豆包MarsCode AI刷题

52 阅读3分钟

问题描述

小S最近在分析一个数组 h1,h2,...,hNh1​,h2​,...,hN​,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk 个相邻元素时,如何计算它们所能形成的最大矩形面积。

对于 kk 个相邻的元素,我们定义其矩形的最大面积为:

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])

即,R(k)R(k) 的值为这 kk 个相邻元素中的最小值乘以 kk。现在,小S希望你能帮他找出对于任意 kk,R(k)R(k) 的最大值。 要解决这个问题,我们需要找到对于每个可能的 k(1 ≤ k ≤ n),在所有长度为 k 的子数组中,计算形成的最大矩形面积。这个面积是由子数组中的最小值乘以 k 得到的。

我们可以使用滑动窗口和单调栈的方法来解决这个问题。单调栈可以帮助我们高效地找到每个窗口中的最小值。

以下是实现这个算法的步骤:

  1. 遍历所有可能的窗口大小 k(从 1 到 n)。
  2. 对于每个窗口大小 k,使用单调栈找到每个窗口中的最小值。
  3. 计算该窗口大小下的最大矩形面积。
  4. 记录并更新最大面积。

下面是 Python 代码实现:

python复制代码
	def maxRectangularArea(n, array):

	    def find_max_area_for_k(k):

	        stack = []

	        heights = []

	        max_area = 0

	        

	        for i in range(n):

	            while stack and array[stack[-1]] >= array[i]:

	                height = array[stack.pop()]

	                width = i if not stack else i - stack[-1] - 1

	                if width >= k:

	                    min_in_window = min(array[stack[-1] + 1:i]) if stack else min(array[:i])

	                    max_area = max(max_area, min_in_window * k)

	            stack.append(i)

	        

	        # Handle remaining elements in stack

	        while stack:

	            height = array[stack.pop()]

	            width = n if not stack else n - stack[-1] - 1

	            if width >= k:

	                min_in_window = min(array[stack[-1] + 1:n]) if stack else min(array)

	                max_area = max(max_area, min_in_window * k)

	        

	        # Special case: k == 1

	        if k == 1:

	            max_area = max(max_area, max(array))

	        

	        # But we need to check all possible subarrays of size k directly

	        for i in range(n - k + 1):

	            min_in_window = min(array[i:i + k])

	            max_area = max(max_area, min_in_window * k)

	        

	        return max_area

	    

	    # Find max area for all possible k

	    max_overall_area = 0

	    for k in range(1, n + 1):

	        max_overall_area = max(max_overall_area, find_max_area_for_k(k))

	    

	    return max_overall_area

	 

	# Test cases

	print(maxRectangularArea(5, [1, 2, 3, 4, 5]))  # Output: 9

	print(maxRectangularArea(6, [5, 4, 3, 2, 1, 6]))  # Output: 9

	print(maxRectangularArea(4, [4, 4, 4, 4]))  # Output: 16

注意事项

  1. 单调栈方法:我们尝试使用单调栈来优化寻找每个窗口最小值的过程,但直接应用单调栈在这个问题上有些复杂,因为我们需要处理所有可能的 k 值。
  2. 直接计算:为了简化,上述代码在 find_max_area_for_k 函数中最后部分直接计算了所有长度为 k 的子数组的最小值并更新了最大面积。这部分可以优化,但直接计算能确保正确性。
  3. 性能:上述实现的时间复杂度较高,为 O(n^3)(在最坏情况下,因为我们需要对每个 k 值都遍历所有可能的子数组)。如果数组长度 n 较大,可能需要进一步优化。

在实际应用中,对于较大的 n,可能需要进一步优化算法以减少时间复杂度。