题目(leetcode题库 11)
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 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
示例 3:
输入:height = [4,3,2,1,4]
输出:16
示例 4:
输入:height = [1,2,1]
输出:2
题解
题目分析
拿到这个题,我们首先从数学角度来分析,要计算容水最多,也就是两根柱子和坐标轴组成的长方形面积最大。我们先将计算公式写出来:
// left表示左边柱子的下标,right表示右边柱子的下标,差为长方形的长
// 以矮柱子为长方形的宽
max = (right - left) * Math.min(height[left], height[right])
上面这个公式来看,基本也就确定了我们要使用的方法就是双指针。
-
临界点
我们这儿的临界点就是:left < right -
保留最大值
每次计算都取最大值max = Math.max(max, ((right - left) * Math.min(height[left], height[right])))
-
如何移动
这是最关键的一步,我们应该怎么移动指针?
因为我们不管移动那一边,我们的长都是变短。在长不变的情况下,要想面积最大,那我们就应该保留高的柱子。也就是多如下一个步骤:if(height[left] > height[right]) { right --; } else { left ++; }
我们将上面的公式合并一下可以这样写:
max = Math.max(max, ((right - left) * (height[left] > height[right] ? height[right--] : height[left++])))
到这里我们的算法核心就算完成了。
完整代码
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let left = 0;
let right = height.length-1;
let max = 0;
while(left < right) {
max = Math.max(max, ((right - left) * (height[left] > height[right] ? height[right--]: height[left++])));
}
return max;
};