Container with most water

1.暴力求解法

用两层嵌套for循环来做,设定一个初值为零的变量maxArea,遍历整个数组,maxArea会等于(j-i)*Math.min(height[i],height[j])与maxArea中的更大值。遍历完毕即得到答案。显然,时间复杂度O(n2),空间复杂度O(1)。

2.双指针

设定left=0,right=height.length-1。如果height[left]<height[right],此时若移动right指针,它只能往前移动,而maxArea会等于这两个指针指向的更小的值乘以他们之间的距离,因此,right指针移动只会使得maxArea减小,因此,此时只能是left指针向右移动。同理,如果不满足height[left]<height[right],则只能是right指针向左移动。这两个指针遍历完整个数组之后就能得到maxArea了。因此,时间复杂度O(n),空间复杂度O(1)。这实际上是贪心算法的应用,在这里贪心算法可以得出最优解。证明:设最优解的左右指针分别为x1,x2。若程序左指针为x1,而右指针在x2右端p处时,就可能错过最优解。因为始终是值更小的那一端指针发生移动,分情况讨论:(1)如果x1>=p,此时右指针p会向左移动,会经过x2,最优解未被错过;(2)如果x1<p,此时x1,x2显然无法构成最优解,因为无论x2多大,x1,x2构成的最优解要么取决于x1,要么取决于比x1还要小的一个数(当x2<x1),而x1,p构成的容器取决于x1,且p距离x1更远。因此,最优解不是x1,x2了。同理可以证明左指针在x1左端的情况下仍可以得到最优解。

代码:

class Solution {
public int maxArea(int[] height) {
int left=0,right=height.length-1,maxArea=0;
while(left<right){
maxArea=Math.max((right-left)*Math.min(height[left],height[right]),maxArea);
if(height[left]<height[right])
left++;
else
right--;
}
return maxArea;
}
}

posted @ 2019-10-11 19:56  xbc121  阅读(101)  评论(0编辑  收藏  举报