11. 盛最多水的容器
题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
思路
做过接雨水的题目之后,感觉这道题和他差不多,所以第一感觉是O(N)可以做出来的。
还是采用的接雨水的思路,用双指针,l和r。
开始的时候,l=0,r=n-1,此时可以计算出存水量,length*depth。depth由最小的左右边界决定,而length由l和r的位置决定。
随着指针的移动,length肯定是慢慢减小的,如果最大存水量出现在中间位置,那么说明depth肯定是很大的。那么,对于l和r,每次移动其最小的那个,直到l和r相遇,此时结束,返回记录的最大水量。
为什么要移动最小的指针,因为,每次移动,length肯定是减小的,要找最大水量,只能找更大depth,所以移动最小的指针,去找下一个边界位置,毕竟depth是由左右边界的最小值决定的。
这个算法没有严格的证明,leetcode官方题解也是这种做法,他的说明更加有说服力
https://leetcode-cn.com/problems/container-with-most-water/solution/sheng-zui-duo-shui-de-rong-qi-by-leetcode-solution/
代码
public int maxArea(int[] height) {
int n = height.length;
int l = 0;
int r = n-1;
int max_ = 0;
while(l<=r){
if(height[l]<height[r]){
max_ = Math.max(max_,(r-l)*height[l]);
l++;
}else{
max_ = Math.max(max_,(r-l)*height[r]);
r--;
}
}
return max_ ;
}