标签:双指针 中等
# 题目
给定一个长度为 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。
1
2
3
2
3
示例 2:
输入:height = [1,1]
输出:1
1
2
2
提示:
n == height.length
2 <= n <= 10^5
0 <= height[i] <= 10^4
# 解析
因为是在力扣贪心系列看到的这题,所以一直在想贪心做法,但是没有找到合适的确定两边界的方法,后面又想了从中间往两边扩展边界计算面积,但是没有很清晰的思路,不知道在什么时候移动左指针,什么时候移动右指针...
看了眼题解,采用双指针的做法,感觉看题解这道题又变得很简单了...从左右两边开始往中间移动,每次移动左右指针较矮的一个,如果两个指针一样高则移动哪个都一样。
- 当左右指针中有比这两个值大的指针,那左右指针移动哪个都无所谓,因为左右指针比中间的指针长度短,漏水,所以左右指针之间的面积 a 更大,因为相对左(右)指针和中间那个更高指针的面积 b 来说,a和b的高度一样,但a的宽度更长,所以面积更大
- 当左右指针中有比这两个值小的指针,那左右指针移动哪个也无所谓,和上面的道理一样,还是左右指针之间的面积更大 所以只有当左右指针中有两个更大值的指针,他们之间的面积才有可能比左右指针的面积大,那移动哪个还有所谓吗?这两个指针都不会出现在结果中,先移动和后移动都无所谓了。
上面的假设都是在左右指针高度相等、且往中间走的情况。
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let left = 0, right = height.length
let maxAreaVal = 0
while (left < right) {
let area = (right - left) * Math.min(height[left], height[right])
if (maxAreaVal < area) maxAreaVal = area
if (height[left] < height[right]) {
left++
} else {
right--
}
}
return maxAreaVal
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18