技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTALG

Container With Most Water

所属馆藏
Algorithm
文件格式
Markdown
原始路径
Algorithm/7-01_Container With Most Water_盛最多水的容器
本文目录13 个章节
  1. 题目 / Problem
  2. 示例 / Examples
  3. 约束 / Constraints
  4. 容量计算 / Area Formula
  5. 解题思路:双指针 / Approach: Two Pointers
  6. 为什么移动较短的一侧? / Why Move the Shorter Side?
  7. 相等高度如何处理? / What If the Heights Are Equal?
  8. JavaScript 实现 / JavaScript Implementation
  9. 执行过程 / Walkthrough
  10. 为什么双指针不会漏掉答案? / Why Does Two Pointers Not Miss the Answer?
  11. 与暴力解法对比 / Comparison with Brute Force
  12. 复杂度 / Complexity
  13. 易错点 / Common Pitfalls

Container With Most Water(盛最多水的容器)

题目 / Problem

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

找出两条垂直线,使它们与 x 轴构成的容器能够容纳最多的水,返回最大容量。容器不能倾斜。

English: Given an integer array height of length n, the ith vertical line has endpoints (i, 0) and (i, height[i]).

Find two lines that, together with the x-axis, form a container holding the maximum amount of water. Return that maximum amount. The container may not be slanted.

示例 / Examples

Example 1

Input:  height = [1,8,6,2,5,4,8,3,7]
Output: 49

下标 1 和 8 组成面积为 49 的最大容器 / Maximum-area container of 49 formed by indices 1 and 8

选择下标 18 的两条线:
Choose the lines at indices 1 and 8:

宽度 / Width  = 8 - 1 = 7
高度 / Height = min(8, 7) = 7
面积 / Area   = 7 × 7 = 49

Example 2

Input:  height = [1,1]
Output: 1
宽度 / Width  = 1
高度 / Height = 1
面积 / Area   = 1

约束 / Constraints

  • n === height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

容量计算 / Area Formula

选择下标 leftright 的两条线时:
For lines at indices left and right:

width = right - left

水面高度由较短的那条线决定,因为水会从较短一侧溢出:
The water height is limited by the shorter line because water spills over that side:

containerHeight = min(height[left], height[right])

因此容器面积为:
Therefore, the container area is:

area = (right - left) × min(height[left], height[right])

解题思路:双指针 / Approach: Two Pointers

初始化两个指针:
Initialize two pointers:

left  = 0
right = height.length - 1

此时两条线之间的宽度最大。每一轮:
The two lines initially have the maximum possible width. In each iteration:

  1. 计算当前容器面积并更新最大值。
    Calculate the current area and update the maximum.
  2. 比较左右两条线的高度。
    Compare the two line heights.
  3. 移动较短一侧的指针,尝试找到更高的线。
    Move the pointer at the shorter line, hoping to find a taller line.
  4. left === right 时停止。
    Stop when left === right.

为什么移动较短的一侧? / Why Move the Shorter Side?

假设:
Suppose:

height[left] < height[right]

当前面积由 height[left] 限制。如果保留左侧较短的线并移动右指针:
The current area is limited by height[left]. If the shorter left line is kept while moving the right pointer:

  • 宽度一定减小。
    The width definitely decreases.
  • 新的容器高度最多仍然是 height[left]
    The new container height is still at most height[left].

因此面积不可能变大。
Therefore, the area cannot increase.

只有移动较短的左侧指针,才有机会遇到一条更高的线,从而弥补宽度减小带来的损失。
Only moving the shorter left pointer may discover a taller line that can compensate for the reduced width.

右侧较短时同理,移动 right
The argument is symmetric when the right side is shorter: move right.

相等高度如何处理? / What If the Heights Are Equal?

如果 height[left] === height[right],移动任意一侧都可以。当前实现移动右指针:
If height[left] === height[right], either pointer may be moved. This implementation moves the right pointer:

if (height[left] < height[right]) {
  left++;
} else {
  right--;
}

保留其中一条相同高度的线,并不会错过更优答案。
Keeping either one of two equal-height lines does not miss a better answer.

JavaScript 实现 / JavaScript Implementation

/**
 * @param {number[]} height
 * @return {number}
 */
function maxArea(height) {
  let left = 0;
  let right = height.length - 1;
  let maximumArea = 0;

  while (left < right) {
    const width = right - left;
    const containerHeight = Math.min(height[left], height[right]);
    const currentArea = width * containerHeight;

    maximumArea = Math.max(maximumArea, currentArea);

    if (height[left] < height[right]) {
      left++;
    } else {
      right--;
    }
  }

  return maximumArea;
}

执行过程 / Walkthrough

height = [1,8,6,2,5,4,8,3,7] 为例:
For height = [1,8,6,2,5,4,8,3,7]:

leftright左高 / Left height右高 / Right height面积 / Area移动 / Move
08178 × 1 = 8left++
18877 × 7 = 49right--
17836 × 3 = 18right--
16885 × 8 = 40right--
15844 × 4 = 16right--
14853 × 5 = 15right--
13822 × 2 = 4right--
12861 × 6 = 6right--

遍历过程中的最大面积是 49
The maximum area encountered is 49.

为什么双指针不会漏掉答案? / Why Does Two Pointers Not Miss the Answer?

每一步都会安全排除一条不可能参与更优解的边界线:
Each step safely eliminates one boundary line that cannot participate in a better solution:

  • 如果左线较短,那么所有以该左线为边界、右端点位于当前 right 左侧的容器,宽度更小且高度不会超过左线,因此面积不可能超过当前面积。
    If the left line is shorter, every container using that left line with a right endpoint inside the current range has smaller width and height no greater than the left line, so none can exceed the current area.
  • 因此可以安全丢弃当前左线并执行 left++
    The current left line can therefore be discarded safely with left++.
  • 右线较短时,同理可以安全执行 right--
    The same reasoning safely discards the right line when it is shorter.

算法不会枚举所有线对,但每次跳过的组合都已经被证明不可能更优。
The algorithm does not enumerate every pair, but every skipped pair has been proven incapable of improving the answer.

与暴力解法对比 / Comparison with Brute Force

暴力解法枚举所有两条线的组合:
Brute force examines every pair of lines:

组合数量 / Number of pairs = n × (n - 1) / 2

时间复杂度为 O(n²),当 n 达到 10^5 时无法接受。
Its time complexity is O(n²), which is too slow when n reaches 10^5.

双指针每轮至少移动一个指针,总共最多移动 n - 1 次。
The two-pointer approach moves at least one pointer per iteration, for at most n - 1 moves total.

复杂度 / Complexity

  • 时间复杂度 / Time: O(n)
  • 空间复杂度 / Space: O(1)

易错点 / Common Pitfalls

  • 容器高度由两条线中较短的一条决定,应使用 Math.min()
    The shorter line determines the water height, so use Math.min().
  • 宽度是下标之差 right - left,不是元素数量。
    Width is the index difference right - left, not the number of array elements.
  • 每轮应移动较短的一侧,而不是较高的一侧。
    Move the shorter side, not the taller side.
  • 必须在移动指针之前计算当前面积。
    Calculate the current area before moving a pointer.
  • 不能把数组柱高相加;水的面积是宽度乘以受限高度。
    Do not add line heights; water area is width multiplied by the limiting height.
  • 题目不允许倾斜容器,因此两侧高度不同时仍以较短侧为水面高度。
    The container cannot be slanted, so unequal sides still use the shorter height as the water level.
457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS