LeetCode 11.盛最多水的容器(左右对撞双指针)
2026/8/5 11:55:38 网站建设 项目流程
class Solution { public int maxArea(int[] height) { //1.暴力求解法(超出时间限制) // int maxArea = 0; // for(int i = 0; i < height.length; i++) { // for(int j = i+1; j < height.length; j++) { // int wide = j - i; // int area = wide * Math.min(height[i],height[j]); // maxArea = Math.max(maxArea,area); // } // } //2.左右对撞双指针 int left = 0, right = height.length-1; int maxArea = 0; while(left < right) { int wide = right - left; int area = wide * Math.min(height[left], height[right]); if(height[left] < height[right]) { left++; }else { right--; } maxArea = Math.max(maxArea, area); } return maxArea; } }

一、核心算法思路

采用左右对撞双指针,时间复杂度 O (n)

  1. 容器面积公式:面积 = 宽度 × 两侧柱子较小高度,水位由更矮的柱子决定(短板效应);
  2. 左指针 left 放在数组最左端,右指针 right 放在数组最右端,初始宽度最大;
  3. 计算当前两根柱子围成的面积,更新全局最大面积;
  4. 核心收缩规则:向内移动高度更小一侧的指针。若移动高柱子,宽度缩小、高度上限不变,面积只会更小;移动矮柱子才有机会遇到更高柱子,得到更大面积;
  5. 不断收缩区间,直到左右指针相遇,最终返回最大面积。

实例运行顺序演示

测试输入:height = [1,8,6,2,5,4,8,3,7]初始状态:left = 0,right = 8,maxArea = 0

leftrightheight[left]height[right]宽度当前面积maxArea操作
0817888左边矮,left++
188774949右边矮,right--
178361849右边矮,right--
168854049等高,right--
158441649右边矮,right--
148531549右边矮,right--
13822449右边矮,right--
12861649右边矮,right--

循环结束,left == right,最终最大面积:49

二、语法 & 概念理解困惑点整理

  1. 两种双指针区分 左右对撞双指针:left 从头、right 从尾,向中间靠拢(本题、两数之和 II); 快慢同向双指针:left、right 同时从起点向右遍历(283 移动零)。

三、踩坑清单

  1. 收缩指针逻辑写反 错误:移动更高一侧的柱子。宽度缩小,水位上限不变,不可能得到更大面积,算法失效。
  2. 循环条件写错 错误:left <= right。指针相遇时宽度为 0,面积为 0,无计算意义,条件应为left < right
  3. 暴力双层循环隐患 双重 for 枚举所有组合复杂度 O (n²),测试用例数据量大时会超时,面试不推荐。
  4. 等高时不知道移动哪边 左右柱子高度相等,left++ 或者 right-- 均可,不影响最终结果。

四、高频易混知识点

  1. 面积本质限制因素:容器储水高度由两根柱子矮者决定,不是高柱子;
  2. 双指针优化原理:利用面积数学规律,舍弃大量不可能更优的组合,把 O (n²) 优化到 O (n);
  3. 数组属于引用类型,本题只读取数组数值,不需要修改原数组。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询