11 盛最多水的容器

2022-7-14 LeetCode双指针

标签:双指针 中等

# 题目

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

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

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

说明:你不能倾斜容器。

示例 1:

img

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
1
2
3

示例 2:

输入:height = [1,1]
输出:1
1
2

提示:

  • n == height.length

  • 2 <= n <= 10^5

  • 0 <= height[i] <= 10^4

# 解析

因为是在力扣贪心系列看到的这题,所以一直在想贪心做法,但是没有找到合适的确定两边界的方法,后面又想了从中间往两边扩展边界计算面积,但是没有很清晰的思路,不知道在什么时候移动左指针,什么时候移动右指针...

看了眼题解,采用双指针的做法,感觉看题解这道题又变得很简单了...从左右两边开始往中间移动,每次移动左右指针较矮的一个,如果两个指针一样高则移动哪个都一样。

  1. 当左右指针中有比这两个值大的指针,那左右指针移动哪个都无所谓,因为左右指针比中间的指针长度短,漏水,所以左右指针之间的面积 a 更大,因为相对左(右)指针和中间那个更高指针的面积 b 来说,a和b的高度一样,但a的宽度更长,所以面积更大
  2. 当左右指针中有比这两个值小的指针,那左右指针移动哪个也无所谓,和上面的道理一样,还是左右指针之间的面积更大 所以只有当左右指针中有两个更大值的指针,他们之间的面积才有可能比左右指针的面积大,那移动哪个还有所谓吗?这两个指针都不会出现在结果中,先移动和后移动都无所谓了。

上面的假设都是在左右指针高度相等、且往中间走的情况。

/**
 * @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