11. 盛最多水的容器
题目描述
- 给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图片来源于LeetCode(侵删)
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
解题之前我们思考这样问题,例如有10块木板,长度各不相同,他们围成一个木桶,那么木桶的容水量取决于什么?答案是长度最短的木板。
所以这道题与木桶问题是相同的。
解法一:
代码如下:
public int maxArea(int[] height) {
if(height.length == 2){
return Math.min(height[0],height[1]);
}
int max = 0;
for(int i = 0;i < height.length;i++){
int weight = 1;
int temp = 0;
for(int j = i + 1;j < height.length;j++){
if(height[j] <= height[i]){ //如果后面木板长度比当前短
temp = weight * height[j];
}else{
temp = weight * height[i]; //如果当前木板是最短的
}
if(temp>max){
max = temp;
}
weight++;
}
}
return max;
}
解法二:
双指针法,通过实现宽度的不断减小,从而再两个指针指向的长度选择最短长度以此来确定面积。
代码如下:
public int maxArea(int[] height) {
int left = 0, right = height.length-1;
int weight = height.length-1;
int max = 0;
while(left < right){
int min = Math.min(height[left],height[right]);
if(min == height[left])
left++;
else
right--;
if(min * weight > max)
max = min * weight;
weight--;
}
return max;
}