题干
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
想法
这道题之前做过,其实还有点像接雨水这道题
接雨水的想法可以参考我写的题解
传送门
我们分析一下这两道题的区别,接雨水这道题,雨水的面积是由左右两边的高度的最小值决定的,这道题也一样
不一样的是这道题盛水是连续的,而不是每个小部分之和
假设我们已经找到了左右两个木条的位置计作left right
那么最多水=Math.min(height[left],height[right])*(right-left);
因为两块木条都可以影响水量,如果不使用双指针就需要两层循环。
于是使用双指针 遍历一次数组,动态规划之前的最大值和现在情况的最大值,
如果左指针比优指针矮,那么左指针右移
因为现在左指针才是短板,它不蹦哒蹦哒不管怎么都不可能变大
。反之同理
于是可以解出来了 直接看代码
Java代码
package daily;
public class MaxArea {
public int maxArea(int[] height) {
//左右指针
int left=0;
int right=height.length-1;
//最大面积 用于动态规划
int area=0;
while(left<right){
//最大面积等于现在的最大面积和之前的最大值
//现在的最大面积等于矮的那个乘️他们之间的距离
area=Math.max(area,Math.min(height[left],height[right])*(right-left));
if(height[left]<=height[right]){
//矮的动
left++;
}
else {
right--;
}
}
return area;
}
public static void main(String[] args){
MaxArea maxArea=new MaxArea();
int [] height={1,8,6,2,5,4,8,3,7};
System.out.println(maxArea.maxArea(height));
}
}