【小白解析leetcode】11.盛水最多的容器
给定一个长度为
n的整数数组height。有n条垂线,第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线,使得它们与
x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。
说明:你不能倾斜容器。
方法1:暴力枚举
通过两层循环,寻找储存最大水量的两个边界
class Solution {
public int maxArea(int[] height) {
int n=height.length;
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
max=Math.max(max,Math.min(height[i],height[j])*(j-i));
}
}
return max;
}
}
设置两个循环变量i和j,i代表左边界,j代表右边界,其中的
max=Math.max(max,Math.min(height[i],height[j])*(j-i));
通过循环找到两垂线相围的最大值,此面积的长为(j-i),宽为min(height[i],height[j])
如何找到最大值?则是通过循环,每次循环得到的面积都与已存在的max比较,将较大数更新max,最终得到面积的最大值
显然,此方法的时间复杂度为O(n2),空间复杂度为O(1)
方法2:双指针
为减小复杂度,应当缩减不必要的暴力枚举
此题符合上述描述,故采用双指针,可设立两个指针,一个指向最左边(left),一个指向最右边(right),向中间移动,如下图:

双指针类似于排序问题,两个指针分别确立两个边界,指针移动时单侧移动,那么应当是哪个指针移动呢?
假设此时right往前移动一格(right--),此面积的高是不变的,因为height[left]<height[right-1],而长减小1,所以面积势必会比之前的小,因此为找到最大值,就应当避免这种很明显的让面积更小的的移动。

故为寻找可能的更大的面积,应当让height更大的边界不动,height更小的边界移动,此情况height[left]<height[right]应当left++,如下图:

此时height[left]>height[right],所以right--,如下图

依次类推
每次循环记录次循环的面积,通过Math.max()记录maxarea(面积的计算方式与方法1类似),最终返回
图示:
以此为例:
输入:[1,8,6,2,5,4,8] 输出:40




此方法,两指针交替移动共遍历一遍数组,故时间复杂度为O(n)
代码:
class Solution {
public int maxArea(int[] height) {
int n=height.length;
int left=0;
int right=n-1;
int maxarea=0;
while(left<right){
maxarea=Math.max(maxarea,(right-left)*Math.min(height[right],height[left]));
if(height[right]<height[left]){
right--;
}else{
left++;
}
}
return maxarea;
}
}
更多推荐



所有评论(0)