Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
题目介绍
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明: 你不能倾斜容器。
示例1
输入:[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.length2 <= n <= 10^50 <= height[i] <= 10^4
解题思路
这道题首先可以从数组的两个端点开始,定义两个指针分别指向数组的第一个和最后一个元素
如上图所示,如果要求 l 和 r 之间的水的容量,根据短板效应,水的容量取决于较短的边的高度,因此 l 和 r 之间的最大水容量是 较短边 * 两条线之间的距离 = 2 * 5
为了一次遍历就可以得到答案,需要记录遍历过程中的较大值 max,遍历结束之后,max 即为最多水的容器
接下来考虑是 l 往后走,还是 r 往前走?
因为不管 l 往后走还是 r 往前走,两条线之间的距离都小了 1,那么肯定是移动较小的边,才有可能得到更多的水容量。
还是以上图举例,如果 l 往后走,较短的边变成了 3,但是如果 r 往前走,较短的边变成了 1,分别计算这两中操作得到的水容量分别是 3 * 4 = 12 和 1 * 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
};