核心思想:首尾双指针
时间复杂度:O(n)(如果使用双重for,复杂度为O(n2),超时)
为什么移动高度较小的指针?
答1:由于容纳的水量是由:两个指针指向的数字中较小值 * 指针之间的距离。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小,我们的目标是乘积要向大的地方变化,所以,移动数字较大的那个指针是不合理的。因此,移动数字较小的那个指针。
答2:在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽底边宽度 −1 变短:
若向内 移动短板 ,水槽的短板min(h[i],h[j]) 可能变大,因此下个水槽的面积可能增大 。
若向内 移动长板 ,水槽的短板min(h[i],h[j]) 不变或变小,因此下个水槽的面积一定变小 ,因为容积取决于最小边。
因此,初始化双指针分列水槽左右两端,循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积。
class Solution {
public int maxArea(int[] height) {
int s_max = 0;
int l_min = 0;
int head = 0;
int tail = height.length - 1;
int s = 0;
while(head < tail){
l_min = Math.min(height[head],height[tail]);
s = l_min * (tail - head);
if(s > s_max){
s_max = s;
}
if(height[head] > height[tail]){
tail--;
}else{
head++;
}
}
return s_max;
}
}