题目
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。画 n 条垂直线,使得垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
分析思路
容器可以容纳的容量为:
m
i
n
(
a
j
,
a
i
)
∗
(
j
−
i
)
min(a_j,a_i)*(j-i)
min(aj,ai)∗(j−i)
2层循环暴力破解肯定不是想要的。
从两端开始计算,比较容器大小,往中间迭代。
第一次迭代,假如是
a
i
a_i
ai最小
那么以
i
i
i为左侧边界,
j
j
j无论如何左移都不可能容量变大。
a
i
∗
(
j
−
i
)
a_i*(j-i)
ai∗(j−i)
所以下次迭代就可以舍弃
i
i
i作为边界
j
j
j同理
代码
package org.example.water;
public class MaxContainer {
private int[] array = new int[]{4,3,6,9,7,4,9};
public int getMaxContainer(){
int maxSum = 0;
int i = 0;
int j = array.length-1;
//双向指针
while(i < j){
int currentSum = Math.min(array[j],array[i])*(j-i);
maxSum = Math.max(currentSum,maxSum);
//当以左侧固定不变为边界时,无论右侧如何移动,容量都不会变大
if(array[i]<array[j]){
i++;
}else{
//当以右侧固定不变为边界时,无论左侧侧如何移动,容量都不会变大
j--;
}
System.out.println("("+i+"-"+j+")最小的"+array[i]+"-"+array[j]+"水"+maxSum);
}
return maxSum;
}
public static void main(String[] args) {
System.out.println(new MaxContainer().getMaxContainer());
}
}