题目:https://leetcode-cn.com/problems/container-with-most-water/

image.png

根据题目的要求,我们可以得知:

  • 需要求的是一个矩形的面积,而不是其它形状的面积。
  • 这个矩形的面积是由高度较低的点来决定。

方法一:暴力解题

最容易想到的方法就是将所有点进行两两组合,得出所有组合的面积,然后取最大的面积即可。但这种方法的时间复杂度为11. 盛最多水的容器 - 图2

  1. function maxArea(height: number[]): number {
  2. let max = 0;
  3. for (let i = 0; i < height.length; i++) {
  4. for (let j = i + 1; j < height.length; j++) {
  5. let tmp = (j - i) * Math.min(height[i], height[j])
  6. if (tmp > max) {
  7. max = tmp
  8. }
  9. }
  10. }
  11. return max
  12. };

上面循环中,第二个 for 循环 let j = i + 1 这个可以减少重复遍历,举一下例子来说明一下:

  1. 1 2 3
  2. 1 x
  3. 2 x x
  4. 3 x x x

假设非负数分别为 1,2,3。那么这三个数两两组合就有 1,2;1,3;2,3。我们假设横轴是 i,而纵轴是 j,表中 x 的地方为重复的组合,我们可以看出不重复的地方,i 和 j 的关系始终为 j = i + 1。

  • 时间复杂度:11. 盛最多水的容器 - 图3
  • 空间复杂度:11. 盛最多水的容器 - 图4

方法二:双指针法

leetcode 官网已经有非常好的双指针法解释,这里不再赘述,下面给出 TypeScript 的解法。

  1. function maxArea(height: number[]): number {
  2. let leftIndex = 0
  3. let rightIndex = height.length - 1
  4. let maxArea = 0
  5. while (leftIndex < rightIndex) {
  6. const area = Math.min(height[leftIndex], height[rightIndex]) * (rightIndex - leftIndex)
  7. maxArea = Math.max(area, maxArea)
  8. height[leftIndex] > height[rightIndex] ? rightIndex-- : leftIndex++
  9. }
  10. return maxArea
  11. }
  • 时间复杂度:11. 盛最多水的容器 - 图5
  • 空间复杂度:11. 盛最多水的容器 - 图6