题目描述
给定 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
分析
方法一:比较笨的方法就是把所有情况都遍历一遍,计算出所有情况。
方法二:采用双指针,开始时一个指针指向开头,另一个指针指向结尾。两段线段之间形成的面积总是受到较短的那条线段决定,同时两段线段之间的距离越大越好。我们使用一个变量存储目前最大的面积,每次计算完当前两个指针指向线段的面积,更新最大面试,并将指向较短的线段的指针向前移动一步。
代码实现
方法一:
public class MaxArea {
public int maxArea(int[] height) {
int max = 0;
for(int i = 0; i< height.length; i++) {
for(int j = i +1; j < height.length ; j++) {
int area = (height[i] > height[j] ? height[j]: height[i]) * (j-i);
if(area > max) {
max = area;
}
}
}
return max;
}
public static void main(String[] args) {
int[] a = {1,8,6,2,5,4,8,3,7};
MaxArea ans = new MaxArea();
System.out.println(ans.maxArea(a));
}
}
方法二:
public class MaxArea2 {
public int maxArea(int[] height) {
int max = 0;
int i = 0;
int j = height.length-1;
while(i < j) {
int min = height[i] < height[j] ? height[i] : height[j];
int area = min * (j -i);
if (area > max)
max = area;
if (min == height[i])
i++;
else
j--;
}
return max;
}
public static void main(String[] args) {
int[] a = {1,8,6,2,5,4,8,3,7};
MaxArea2 ans = new MaxArea2();
System.out.println(ans.maxArea(a));
}
}