图解题库 / 对撞双指针

11. 盛最多水的容器

中等 含交互动画

学完这道你应该能: 说清它为什么用「对撞双指针」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

每个数是一条竖线的高度。选两条线和 x 轴围成容器,求最大盛水面积

height = [1, 8, 6, 2, 5, 7]
输出 = 24

思路解析

枚举所有线对,n² 个组合。n 一大就慢。换个思路:从「最宽」的一对开始,每步只放弃一条注定没希望的线。

l、r 在最左最右(宽度最大)。面积由矮的那条决定,所以移走矮的——因为留着它、宽度还变小,面积只会更差;移走它才可能遇到更高的线、翻盘。

l=0, r=5:最宽时面积 = min(1,7)×5 = 5。左边的 1 太矮,移走它(l 右移)。

l=1, r=5:现在 min(8,7)×4 = 28,刷新最大值!这次右边 7 较矮,移走它(r 左移)。

l=1, r=4:min(8,5)×3 = 15,没超过 28。右边 5 矮,r 左移。

l=1, r=3:min(8,2)×2 = 4,更小。继续移矮的右边。

l=1, r=2 · 收束:最后 min(8,6)×1 = 6。l、r 即将相遇,全程最大就是 28

面积受限于矮的一边,所以放弃矮的才有翻盘机会——这是对撞双指针里的贪心选择。

参考代码(Python)

Python
1l, r, best = 0, len(height) - 1, 0
2while l < r:
3    area = min(height[l], height[r]) * (r - l)
4    best = max(best, area)
5    if height[l] < height[r]: l += 1     # 移走较矮的左
6    else: r -= 1                         # 否则移右
7return best

复杂度分析

  • 时间复杂度:O(n) —— 双指针走一遍
  • 空间复杂度:O(1) —— 几个变量

套路模板

记住骨架:两端收缩、每步移走限制结果的那一端。和「有序找一对」的双指针同形,区别只是「移谁」的判据。

Python
1# 两端向中间收、每步放弃"拖后腿"的一边
2l, r, best = 0, n - 1, 初值
3while l < r:
4    best = 更新(best, 用 l, r 算的值)
5    if 谁是瓶颈 == 左: l += 1
6    else: r -= 1

易错点

  • 移走较高的一边 → ✅ 移走较矮的一边(面积由矮边决定,移高边宽度还变小、必更差)
  • 面积用较高的高度 → ✅ 用 min(左,右) 高度(水从矮的一边溢出)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →198. 打家劫舍 ← 返回题库