问题介绍:给定n个非负整数$a_{1},a_{2},...,a_{3}$,其中$a_{i}$代表坐标($i$,$a_{i}$)上的一个点。在每个点上绘制一条直线,
其中每个代表坐标(
i
i
i,
a
i
a_{i}
ai)上的一个点。 绘制n条垂直线,找到两条线,其中两条线的两个端点位于(
i
i
i,
a
i
a_{i}
ai)和(
i
i
i,0),使这两条线与x轴一起形成一个上部开口的容器,怎样才能使得容器装的水尽可能的多?
上面的图片表示输入的数组为[1,8,6,2,5,4,8,3,7]时,最大储水面积(蓝色的部分)为49
问题分析:
1)当选择的线为
a
1
a_{1}
a1和
a
n
a_{n}
an时,面积为(n - 1)*min{
a
1
a_{1}
a1,
a
n
a_{n}
an}。
2)底边最长为(N - 1)。
根据以上的分析可知,如果有更好的解,
b
a
s
e
∗
h
e
i
g
h
t
base*height
base∗height > (n - 1)*min{
a
1
a_{1}
a1,
a
n
a_{n}
an},那么这个解的高height一定比 min{
a
1
a_{1}
a1,
a
n
a_{n}
an}要高,因为base < (N - 1)
如果
a
1
a_{1}
a1>
a
n
a_{n}
an,则将
a
n
a_{n}
an向前移一位,看min{
a
1
a_{1}
a1,
a
n
−
1
a_{n-1}
an−1}的高度是否比之前高。否则则将
a
1
a_{1}
a1向后移动一位,观察min{
a
2
a_{2}
a2,
a
n
a_{n}
an}的高度是否比之前高。
代码如下:
public class Solution {
public int maxArea(int[] height)
{
int l = 0;
int r = height.length - 1;
int maxarea = 0;
while (l < r)
{
maxarea = Math.max(maxarea, (r - l)* Math.min(height[r],height[l]));
if(height[r] > height[l]) {
r--;
}else
{
l++;
}
}
return maxarea;
}
}
还有一个暴力解法
public class Solution {
public int maxArea(int[] height) {
int maxarea = 0;
for (int i = 0; i < height.length; i++)
for (int j = i + 1; j < height.length; j++)
maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i));
return maxarea;
}
}