算法-数组-盛最多水的容器

124 阅读1分钟

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

暴力破解方法

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

数组循环遍历,因为用两层for循环,每层执行n次,O(N2)O(N²),效率比较低,执行会超时。

双指针法

    public int maxArea2(int[] a) {
        int l = 0; //左指针
        int r = a.length - 1; //右指针
        int maxArea = 0;

        while (l < r) {
            int height = Math.min(a[l], a[r]);
            int area = (r - l) * height;
            maxArea = Math.max(area, maxArea);
            if (a[l] <= a[r]) { //左边指针的高度比较矮,左指针往右移动
                l++;
            } else {
                //右边指针的高度比较矮,右指针往左移动
                r --;
            }
        }

        return maxArea;
    }

首先将指针分别定位于数组的起始位置和末尾位置,然后比较两个指针所指向的高度,那边矮,就往中间靠拢,直到两个指针重合。时间复杂度:O(N)O(N),双指针总计最多遍历整个数组一次。