Leetcode 每日一题: 盛水最多的容器

355 阅读1分钟

题目:

image-20200418135635367
第一反应是O(n^2^)的暴力破解法,从前往后遍历,不过这明显不是正确的题解.那么要做到对数级别或者O(n),必须要减少比较的次数,或者说减少没必要的尝试.这里有一个比较好的思路,也是力扣的官方解,就是利用双指针.

解析

从题目可以看出来,水的体积 :

V = L(长) × H(高)
L = left(右柱的下标) - right(左柱的下标)
H = Min( 左柱的高度 , 右柱的高度)

大致思路 : 存在一个变量 max 记录出现过的最大体积, 然后开始移动指针,并记录每一次的V,大于max则更新.

移动指针的规则: 总是移动柱高小的一边的位置. 如果左柱高度小于右柱高度,则 left++,反之 right--;

为何是移动小的一边?

比如左柱下标2,高度4,右柱下标5,高度是6. 那么V = L( 5 - 2 ) × H(min( 4 , 6 )) = 12

所以,L是随着遍历越来越小, min(4,6)要变大只能提高下限

Java实现

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