LeetCode 11. 盛最多水的容器

121 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第34天,点击查看活动详情.

11. 盛最多水的容器

题目描述

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

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

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

说明:你不能倾斜容器。 在这里插入图片描述

解题思路

思路一: 双指针

矩形的面积与两个因素有关:

  • 矩形的长度:两条垂直线的距离
  • 矩形的宽度:两条垂直线其中较短一条的长度

因此,要矩形面积最大化,两条垂直线的距离越远越好,两条垂直线的最短长度也要越长越好。
面积公式如下:
res(i,j)=min(height[left],height[right])(rightleft)res(i, j) = min(height[left], height[right]) * (right - left)

我们设置两个指针 left 和 right,分别指向数组的最左端和最右端。此时,两条垂直线的距离是最远的,若要下一个矩形面积比当前面积来得大,必须要把 height[left] 和 height[right] 中较短的垂直线往中间移动,看看是否可以找到更长的垂直线。

算法流程:
初始化: 双指针 left , right 分别指向数组的最左端和最右端;
循环收窄: 直至双指针相遇时跳出;
更新面积最大值 res ;
较短的垂直线往中间移动;
返回值: 返回面积最大值 res 即可;

实现代码如下:

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let left = 0, 
        right = height.length - 1, 
        res = 0;
    while(left < right) {
        res = height[left] < height[right] ? 
            Math.max(res, (right - left) * height[left++]): 
            Math.max(res, (right - left) * height[right--]); 
    }
    return res;
}; 
 
  • 时间复杂度 O(n): 双指针总计最多遍历整个数组一次。
  • 空间复杂度 O(1): 变量 left , right , res 使用常数额外空间。

参考资料

双指针解法 - 盛最多水的容器 - 力扣(LeetCode)

11. 盛最多水的容器(双指针,清晰图解) - 盛最多水的容器 - 力扣(LeetCode)