必须从最宽开始,因为初始宽度最大且面积=宽度×较短边高度,只有先保证宽度最大,才可能获得全局最大值;每次只移动较短边指针,因移动较长边必然导致面积减小,而移动较短边有望提升短板高度从而增大面积;通过贪心剪枝确保不漏最优解。

直接用双指针从两端向中间收缩,每次移动较短边的指针,就能在 O(n) 时间内找到最大盛水量。
为什么必须从最宽开始
容器面积 = 宽度 × 较短边高度。初始时左右指针分别在首尾,宽度最大。这是唯一可能取得全局最大值的起点——因为任何其他组合宽度都更小,除非高度显著提升,否则无法超越当前值。
- 宽度随指针靠近持续减小,所以要争取在宽度尚大时,尽快找到更高的“短板”
- 如果一开始就缩窄宽度,会永久丢失“最宽+中等高”这种潜在优解
为什么只移动较短边的指针
移动长边没有意义:宽度变小,而决定高度的仍是短边,新面积必然更小。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 假设 left 高度为 3,right 高度为 8,当前面积 = (j−i)×3
- 若右移 right,新宽度减 1,新高度 ≤ 3(因为 left 还是短板),面积一定下降
- 若右移 left,新宽度减 1,但新 left 高度可能为 5、7、9……只要 ≥ 3,就存在面积更大的可能
怎么保证不漏掉最优解
每轮舍弃的都是“已知不可能更好”的组合。例如当前 left=0, right=n−1,且 height[0] 较小,那么所有以 height[0] 为左边界、其他任意位置为右边界的容器,面积都不超过当前值。
- 因为它们宽度 ≤ 当前宽度,且高度 ≤ height[0]
- 所以这些组合全被安全剪枝,无需枚举
- 算法本质是贪心+剪枝,不是穷举,但数学上可证明覆盖全部候选最优解
代码实现要点
只需两个变量维护指针和一个变量记录最大值,无额外空间开销。
- 初始化 left=0,right=数组末尾索引
- 循环条件是 left
- 每次计算面积后,比较 height[left] 和 height[right],移动较小者
- 注意整数乘法可能溢出,但题目数据范围(height[i]≤10⁴,n≤10⁵)下 int 足够










