题目描述:
小S最近在分析一个数组 h1,h2,...,hN,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 k 个相邻元素时,如何计算它们所能形成的最大矩形面积。
对于 k 个相邻的元素,我们定义其矩形的最大面积为:
R(k)=k×min(h[i],h[i+1],...,h[i+k−1])
即,R(k) 的值为这 k 个相邻元素中的最小值乘以 k。现在,小S希望你能帮他找出对于任意 k,R(k) 的最大值。
测试样例:
- 输入:
n = 5, array = [1, 2, 3, 4, 5]
- 输出:
9
思路解析:
-
理解问题:我们需要找到数组中任意 k 个相邻元素所能形成的最大矩形面积。这个面积由 k 个元素中的最小值决定。
-
数据结构选择:我们可以使用数组来存储高度信息。
-
算法步骤:
- 遍历所有可能的 k 值,从 1 到 n。
- 对于每个 k,遍历数组,计算以每个元素为起点的窗口的面积。
- 在每个窗口中找到最小的高度。
- 计算当前窗口的面积,并更新最大面积。
图解:
假设数组为 [1, 2, 3, 4, 5]
,我们可以通过以下步骤来计算最大矩形面积:
- 当 k = 1 时,最大面积为 5(即最大高度)。
- 当 k = 2 时,最大面积为 4(即
[4, 5]
的最小值 4 乘以 2)。 - 当 k = 3 时,最大面积为 6(即
[3, 4, 5]
的最小值 3 乘以 3)。 - 当 k = 4 时,最大面积为 8(即
[2, 3, 4, 5]
的最小值 2 乘以 4)。 - 当 k = 5 时,最大面积为 5(即
[1, 2, 3, 4, 5]
的最小值 1 乘以 5)。
最终,最大面积为 9。
代码详解:
public class Main { public static int solution(int n, int[] array) { int maxArea = 0;
// 遍历所有可能的 k 值,从 1 到 n
for (int k = 1; k <= n; k++) {
// 遍历数组,计算每个窗口的面积
for (int i = 0; i <= n - k; i++) {
// 找到当前窗口的最小高度
int minHeight = array[i];
for (int j = i + 1; j < i + k; j++) {
if (array[j] < minHeight) {
minHeight = array[j];
}
}
// 计算当前窗口的面积
int area = k * minHeight;
// 更新最大面积
if (area > maxArea) {
maxArea = area;
}
}
}
return maxArea;
}
public static void main(String[] args) {
// 测试用例
System.out.println(solution(5, new int[]{1, 2, 3, 4, 5}) == 9);
System.out.println(solution(6, new int[]{2, 1, 5, 6, 2, 3}) == 10);
}
}
知识总结
新知识点:
- 滑动窗口:在数组中滑动窗口是一种常见的技巧,用于解决需要连续子数组的问题。
- 最小值计算:在滑动窗口中找到最小值是一个关键步骤,可以通过遍历窗口内的元素来实现。
理解与建议:
- 滑动窗口:滑动窗口技巧在处理连续子数组问题时非常有用,尤其是在需要动态调整窗口大小的情况下。
- 最小值计算:在滑动窗口中找到最小值可以通过简单的遍历实现,但在更复杂的情况下,可以使用优先队列或单调栈来优化。