[LeetCode] 11. Container With Most Water Java

题目:Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

分析:引用自https://segmentfault.com/a/1190000008824222减少循环的核心思路是省去没有必要的遍历,并且确保所需的答案一定能被遍历到
假设现在有一个容器,则容器的盛水量取决于容器的底和容器较短的那条高
则我们可以从最大的底长入手,即当容器的底等于数组的长度时,则容器的盛水量为较短边的长乘底
可见 只有较短边会对盛水量造成影响,因此移动较短边的指针,并比较当前盛水量和当前最大盛水量。直至左右指针相遇。

主要的困惑在于如何移动双指针才能保证最大的盛水量被遍历到
假设有左指针left和右指针right,且left指向的值小于right的值,假如我们将右指针左移,则右指针左移后的值和左指针指向的值相比有三种情况

  1. 右指针指向的值大于左指针
    这种情况下,容器的高取决于左指针,但是底变短了,所以容器盛水量一定变小

  2. 右指针指向的值等于左指针
    这种情况下,容器的高取决于左指针,但是底变短了,所以容器盛水量一定变小

  3. 右指针指向的值小于左指针
    这种情况下,容器的高取决于右指针,但是右指针小于左指针,且底也变短了,所以容量盛水量一定变小了

综上所述,容器高度较大的一侧的移动只会造成容器盛水量减小
所以应当移动高度较小一侧的指针(这样盛水量才可能变大),并继续遍历,直至两指针相遇。

代码:

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

 

posted @ 2018-02-27 10:35  荒野第一快递员  阅读(169)  评论(0编辑  收藏  举报