LeetCode第十一题(盛最多水的容器)

190 阅读1分钟

双层for循环(Java)

存在问题: 超时

class Solution {
    public int maxArea(int[] height) {
        int max = Integer.MIN_VALUE;//保存最大值
        for(int i = 0; i < height.length - 1; i++){
            for(int j = i + 1; j < height.length; j++){
                int h = Math.min(height[i], height[j]);//容器实际高度
                max = Math.max(max, h * (j - i)); 
            }
        }
        return max;
    }
}

双层for循环-剪枝优化(Java)

剪枝优化: 当前容器理论上的最大高度为height[i],最大宽度为height.length - i - 1,在保持当前max下,容器宽度减小时所需最小高度为max / (height.length - i - 1),换言之:若height[i]小于max / (height.length - i - 1),内层for循环的所有max不增,故直接剪枝

class Solution {
    public int maxArea(int[] height) {
        int max = Integer.MIN_VALUE;//保存最大值
        for(int i = 0; i < height.length - 1; i++){
            //当前容器理论上的最大高度为height[i],最大宽度为height.length - i - 1
            if(height[i] > max / (height.length - i - 1)){//最大高度小于max / (height.length - i - 1)时,剪枝优化
                for(int j = i + 1; j < height.length; j++){
                    int h = Math.min(height[i], height[j]);//容器实际高度
                    max = Math.max(max, h * (j - i)); 
                }
            }
        }
        return max;
    }
}

双指针(Java)

核心思想: 容器可容纳的水量 = 左、右指针之间的间隔(容器的宽度) * 左、右指针指向边界(容器的高度)的较小值,初始时容器的宽度最大,在指针移动过程中,容器的宽度必然减小,只有当指针指向边界的值增大时,容器可容纳的水量才有可能增大。

class Solution {
    public int maxArea(int[] height) {
        int max = Integer.MIN_VALUE;//保存最大值
        int left = 0, right = height.length - 1;//指向容器的左、右边界的双指针
        while(left != right){
            max = Math.max(max, Math.min(height[left], height[right]) * (right - left));
            //移动指向边界值较小的指针
            if(height[left] <= height[right])
                left++;
            else
                right--;
        }
        return max;
    }
}