思路: 按照这道题的意思,这个最大值是通过区间长度和这个区间里的最小值决定的,我们一开始是无法确定区间k的大小的,但是连续k个里面的最小值我们是可以直接知道的。我们可以将k看成是变量,随着array里面的元素变化,我们可以假设array[i]是连续k个元素的最小值,然后我们就可以求这个k了,我们可以利用两个指针,从array[i]的位置开始向数组的两边移动,移动的条件是下一个元素比array[i]大,因为这个最小值可以出现在连续k个元素的任何地方。
当这两个指针停下来后,我们计算这个两个指针的距离,就是k的值。然后我们遍历完array[i]的全部元素后就可以得到最大值了。
public class Main {
public static int solution(int n, int[] array) {
// Edit your code here
int left=0,right=0;
int max=0,temp=0,k=0;
for (int i = 0; i < n; i++) {
left=i;
right=i;
while(left>0){
if (array[left-1]>=array[i]) {
left--;
}else{
break;
}
}
while(right<n){
if(right==n-1){
break;
}
if (array[right+1]>=array[i]) {
right++;
}else{
break;
}
}
k=right-left+1;
temp=array[i]*k;
System.out.println(array[i]+"*"+k+"="+temp);
max= Math.max(temp, max);
}
return max;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(5, new int[]{1, 2, 3, 4, 5}) == 9);
}
}
代码解释:
-
变量定义:
left和right:这两个变量用于表示当前考虑的最小值array[i]在数组中的左右边界。max:用于存储计算过程中遇到的最大矩形面积。temp:用于存储当前计算得到的矩形面积。k:表示当前考虑的区间长度。
-
主循环:
- 遍历数组中的每个元素,将当前元素视为可能的最小值。
left=i; right=i;:初始化左右指针,指向当前元素。
-
向左扩展:
- 使用
while循环,从当前元素向左扩展,直到遇到一个小于当前元素的值或到达数组开头。
- 使用
-
向右扩展:
- 使用
while循环,从当前元素向右扩展,直到遇到一个小于当前元素的值或到达数组末尾。
- 使用
-
计算区间长度和矩形面积:
k=right-left+1;:计算当前区间的长度。temp=array[i]*k;:计算当前区间的矩形面积。
-
更新最大面积:
max= Math.max(temp, max);:将当前计算得到的矩形面积与已知的最大面积进行比较,更新最大面积。
总结:
在解决这个数组最大矩形面积问题时,我们采用了一种巧妙的方法,将问题分解为寻找每个元素作为最小值时的最大区间长度。这种方法的核心在于理解矩形面积的计算公式: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])。通过观察公式,我们可以发现,当确定了最小值时,区间长度越大,矩形面积就越大。
代码的实现过程中,我们使用了双指针技巧,分别从当前元素向左右两边扩展,寻找符合条件的区间。这种技巧在解决数组问题时非常常见,它可以帮助我们在O(n)的时间复杂度内解决问题,避免了暴力解法带来的高时间复杂度。
在代码编写过程中,我们需要注意以下几个关键点:
- 边界条件: 在向左或向右扩展时,要确保不会越界。
- 循环终止条件: 当遇到小于当前最小值的元素时,停止扩展。
- 区间长度计算: 正确计算区间长度是求解问题的关键。
- 最大面积更新: 在每次计算完矩形面积后,要及时更新最大面积。