题目:盛最多水的容器

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

说明:你不能倾斜容器,且 n 的值至少为 2。 title 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例1

输入: [1,8,6,2,5,4,8,3,7]
输出: 49

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water/

解题思路:双指针法

首先假设高为h,两线距离为len,我们知道求体积v的公式是h*len,那么根据公式可以知道如果要求出最大体积那么len应该是尽可能的长,但是由于受到h的限制只能取相对短一端来计算
先初始设置左右两线位置为l=0r=height.length-1如下图: 0011-01.png 如上图,先从h[l]和h[r]取最短的作为h,那么v=h[l]*(r-l)=8,在计算完后l往右移动,为什么是l往右移动而不是r往左移动呢呢,因为已知计算vh应取最短一侧,那么当前长度已为最远情况下h不变就不可能超过原来的值 0011-05.png 如上图,假设r往左移动,那么按上面的公式计算出的结果v=7,所以要取得最大体积只能把短的一边舍弃寻找更高的值 0011-02.png 如上图l往左移动后v=h[r]*(r-l)=49,那么这个值是大于之前计算的v

代码实现

let maxArea = function (height) {
    let h1 = 0,
        h2 = 0,
        w = 0,
        v = 0,
        maxv = 0,
        l = 0,
        r = height.length - 1;
    while (r - l > 0) {
        h1 = height[l];
        h2 = height[r];
        if (h1 > h2) {
            v = h2 * (r - l)
            r--
        } else {
            v = h1 * (r - l)
            l++
        }
        maxv = Math.max(maxv, v)
    }
    return maxv
};