双层for循环(Java)
存在问题: 超时
class Solution {
public int maxArea(int[] height) {
int max = Integer.MIN_VALUE;//保存最大值
for(int i = 0; i < height.length - 1; i++){
for(int j = i + 1; j < height.length; j++){
int h = Math.min(height[i], height[j]);//容器实际高度
max = Math.max(max, h * (j - i));
}
}
return max;
}
}
双层for循环-剪枝优化(Java)
剪枝优化: 当前容器理论上的最大高度为height[i],最大宽度为height.length - i - 1,在保持当前max下,容器宽度减小时所需最小高度为max / (height.length - i - 1),换言之:若height[i]小于max / (height.length - i - 1),内层for循环的所有max不增,故直接剪枝
class Solution {
public int maxArea(int[] height) {
int max = Integer.MIN_VALUE;//保存最大值
for(int i = 0; i < height.length - 1; i++){
//当前容器理论上的最大高度为height[i],最大宽度为height.length - i - 1
if(height[i] > max / (height.length - i - 1)){//最大高度小于max / (height.length - i - 1)时,剪枝优化
for(int j = i + 1; j < height.length; j++){
int h = Math.min(height[i], height[j]);//容器实际高度
max = Math.max(max, h * (j - i));
}
}
}
return max;
}
}
双指针(Java)
核心思想: 容器可容纳的水量 = 左、右指针之间的间隔(容器的宽度) * 左、右指针指向边界(容器的高度)的较小值,初始时容器的宽度最大,在指针移动过程中,容器的宽度必然减小,只有当指针指向边界的值增大时,容器可容纳的水量才有可能增大。
class Solution {
public int maxArea(int[] height) {
int max = Integer.MIN_VALUE;//保存最大值
int left = 0, right = height.length - 1;//指向容器的左、右边界的双指针
while(left != right){
max = Math.max(max, Math.min(height[left], height[right]) * (right - left));
//移动指向边界值较小的指针
if(height[left] <= height[right])
left++;
else
right--;
}
return max;
}
}