题目
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
输入:[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
我的思路
这题思路上很简单,如果用两个for循环一下就写出来了,但是超出时间限制
var maxArea = function(height) {
var len = height.length;
var size = 0;
var maxsize = 0;
var small = 0;
var width = 0;
for(var i=0;i<len-1;i++)
{
for(var j=i+1;j<len;j++)
{
small = Math.min(height[i],height[j]);
width = j-i;
size = width * small;
if(size>maxsize)
{
maxsize = size;
}
}
}
return maxsize;
};
题解
应该用双指针,双指针代表的是可以作为容器边界的所有位置的范围。在一开始,双指针指向数组的左右边界,表示数组中所有的位置都可以作为容器的边界,因为我们还没有进行过任何尝试。在这之后,我们每次将对应的数字较小的那个指针往另一个指的方向移动一个位置,就表示我们认为这个指针不可能再作为容器的边界了。
当某一边界确定时,则它为短期内的极大值,即使后续遇见更大值,其前一极大值与当前边界值已组成了最高的高
function doublePoint(height){ // 左边界指针 let left=0 // 右边界指针 let right=height.length-1 // 最大面积 let maxArea=0 // 中止循环条件:当左右边界指针重合或左边界超出右边界 while(right>left) { // 计算当前面积:(right-left)为x轴长,min(height[right],height[left])为y轴高 let tempArea=(right-left)*Math.min(height[right],height[left]) // 当前面积大于记录的最大值,则更改最大值 if(tempArea>maxArea)maxArea=tempArea // 当右边界值更高,则使其左边界向中心移动 // 当左边界值更高,则使其右边界向中心移动 // 直至不满足循环 if(height[right]>height[left])left++ else right-- } return maxArea }