leetcode刷题(40)——11.盛水最多的容器

一、题目

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

说明:你不能倾斜容器,且 n 的值至少为 2。

leetcode刷题(40)——11.盛水最多的容器_第1张图片

二、思路——双指针

总体思路:

设置左、右指针分别指向数组的左右两端,相当于容器的左、右边界,计算容器容量。按规则移动指针,记录容量的最大值并返回。

具体实现:

(1)容器的容量:

设左右指针 l、r,对应的边界分别为 h[l]、h[r],容器的容量是由较小的边界决定的,为
左 右 边 界 中 的 较 小 值 × 左 右 指 针 的 距 离 左右边界中的较小值 \times 左右指针的距离 ×
S ( l , r ) = m i n ( h [ l ] , h [ r ] ) × ( r − l ) S(l, r) = min(h[l], h[r]) \times (r - l) S(l,r)=min(h[l],h[r])×(rl)

(2)指针移动规则:

  • 首先,每次移动指针时,都会使得底边的长度减一。
  • 移动指针有两个选择,一个是移动小边界对应的指针,一个是移动大边界对应的指针。
  • 若移动大边界对应的指针,则 m i n ( h [ l ] , h [ r ] ) min(h[l], h[r]) min(h[l],h[r]) 不变或者变小,那么容器的容量只会变小。也就是说,这个指针对应的数不会再作为容器的边界了。
  • 若移动小边界对应的指针,则 m i n ( h [ l ] , h [ r ] ) min(h[l], h[r]) min(h[l],h[r]) 可能变大,那么容器的容量也可能变大。

综上,我们移动指针的规则就是:移动小边界对应的指针

三、代码

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

你可能感兴趣的:(leetcode刷题)