LeetCode刷题记录之盛水最多的容器

174 阅读2分钟

题目描述

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, //ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

基本思路

水的容器等于容器的长度*高度,木桶的长度也就是数组的索引,高度也就是数组中索引对应的值。

根据木桶效应我们知道,盛水的数量主要看水的短板,也就是容器高度更短的那边决定了盛水的体积。

解法1:暴力求解法

暴力求解法也就是穷举法,使用两种循环遍历数组。第一层遍历代表当前容器的左边界,第二层遍历代表容器的右边界。

双层遍历的时间复杂度也就是O(n^2),空间复杂度是O(1)

解法2: 双指针法

双指针法是在穷举法的基础上进行优化,我们使用两个指针i,j,i从左边界向右边界出发,j从右边界向左边界出发。我们先i,j区间的面积进行计算,高度当然是选择i,j之间更小的(木桶效应)。

长度和我们知道如何计算,我们需要确认一下双指针的移动规则,我们知道在两个指针对应的高度,我们需要选择更小的那个。所以我们在使用双指针移动过程中,移动高度更低的那个指针。

代码内容

解法1,时间复杂度(O(n^2)),空间复杂度O(1))

class Solution {
    public int maxArea(int[] height) {
        int max = 0;
        for (int i = 0; i < height.length - 1; i++) {
            for (int j = i + 1; j < height.length; j++) {
                int area = (j - i) * Math.min(height[i], height[j]);
                if (area > max) {
                    max = area;
                }
            }
        }

        return max;
    }
}

解法2,时间复杂度(O(n),空间复杂度O(1))

  public int maxArea(int[] height) {
        int max = 0;
        int i = 0;
        int j = height.length - 1;
        while (i != j) {
            int heigit = height[i] > height[j] ? height[j--] : height[i++];
            //+1是因为上面已经--了或++了
            int area = (j - i  + 1) * heigit;
            max = Math.max(area,max);
        }

        return max;
    }