[路飞]_盛最多水的容器

148 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

leetcode-11 盛最多水的容器

题目介绍

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明: 你不能倾斜容器。

示例1

image.png

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49

示例2

输入: height = [1,1]
输出: 1

提示:

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

解题思路

这道题首先可以从数组的两个端点开始,定义两个指针分别指向数组的第一个和最后一个元素

1646236379.png

如上图所示,如果要求 lr 之间的水的容量,根据短板效应,水的容量取决于较短的边的高度,因此 lr 之间的最大水容量是 较短边 * 两条线之间的距离 = 2 * 5

为了一次遍历就可以得到答案,需要记录遍历过程中的较大值 max,遍历结束之后,max 即为最多水的容器

接下来考虑是 l 往后走,还是 r 往前走?

因为不管 l 往后走还是 r 往前走,两条线之间的距离都小了 1,那么肯定是移动较小的边,才有可能得到更多的水容量。
还是以上图举例,如果 l 往后走,较短的边变成了 3,但是如果 r 往前走,较短的边变成了 1,分别计算这两中操作得到的水容量分别是 3 * 4 = 121 * 4 = 4,因此,我们应该移动较短边的指针

当两个指针相遇的时候,说明已经遍历完了整个数组,此时 max 存放的值就是这道题所要求的最多水的容器

解题代码

var maxArea = function(height) {
    let l = 0, r = height.length - 1
    let max = 0
    while (l < r) {
        max = Math.max(max, Math.min(height[l], height[r]) * (r - l))
        if (height[l] < height[r]) l++
        else r--
    }
    return max
};