题目描述:给定 n 个非负整数 a1,a2,...,an,其中每个代表一个坐标(i,ai)。n 个垂直线段例如由(i,ai)和(i,0)确定
找到两个线段,与 x 轴形成一个容器,使其包含最多的水。备注:你不必倾倒容器。
示例: 输入为 1 2 3 4 对应的图则为:在该示例中 水的容量最大是4(红色两条线段之间)
解题思路:
1.暴力枚举:将每条线段与其他线段 分别组合 求最大值 如示例中的 则是 (1,2)(1,3)(1,4)(2,3)(2,4)(3,4)
共有n*(n-1)/2种组合 时间复杂度为O(n^2)
2.第二种则是 从两端向中间找 去掉短的边 这么做的原因在于:从两边开始找,宽度最大,此时向中间移动时,必然宽度变小。如此一来,想求最大,只有高度增长才有可能做到,这个过程中 去掉了一些短的边
示例 输入 3 1 4 2
第一种做法 则有 (3,1) (3,4) (3,2) (1,4) (1,3) (4,2)
第二种做法 则是 (3,2) (3,4) (1,4) 相比第一种做法 可以看到 当左边是2的时候 方法二并不会去找(3,1)因为宽度变窄了 要想面积变大 则高度要增长才行 而 和之前已经遍历过的(3,2)比起来 (3,1)是不可能是最大值的
两种解法的代码如下:均通过leetcode
package leetcode;
public class ContainerWater {
//解法一 暴力枚举
public static int maxArea1(int[] height) {
if(height==null || height.length==1)
return 0;
else{
int i=0;
int j=0;
int max=0;
int temp = 0;
for(i=0;i<height.length;i++){
for(j=i+1;j<height.length;j++){
if(height[j]>height[i]){
temp=(j-i)*height[i];
if(max<temp)
max=temp;
}else{
temp=(j-i)*height[j];
if(max<temp)
max=temp;
}
}
}
return max;
}
}
//解法二
public static int maxArea2(int[] height) {
//只有一条边 不能装水
if (height.length<2){
return 0;
}
int left = 0;
int right = height.length-1;
int maxV = 0;
while (left<right){
int v = Math.min(height[left],height[right])*(right-left);
maxV = Math.max(v,maxV);
if (height[left]<height[right]){
left++;
}else {
right--;
}
}
return maxV;
}
public static void main(String[] args) {
int[] height = new int[] {1,2,3,4};
int maxArea = maxArea1(height);
System.out.println(maxArea);
}
}
输出:4
加加加油!!!!!!!!!!!