LeetCode 11. 盛最多水的容器(Java 双指针详解)
题目描述给定一个长度为n的整数数组height。有n条垂线第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。说明你不能倾斜容器。示例 1plaintext输入[1,8,6,2,5,4,8,3,7] 输出49 解释图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下容器能够容纳水表示为蓝色部分的最大值为 49。示例 2plaintext输入height [1,1] 输出1提示n height.length2 n 10^50 height[i] 10^4解题思路双指针法核心思路这道题最高效的解法是双指针法时间复杂度O(n)空间复杂度O(1)完美适配题目数据范围。指针初始化左指针left指向数组起始位置最左边右指针right指向数组末尾最右边。面积计算容器的容积 两指针间距宽度 × 两指针指向的较小高度高度公式min(height[left], height[right]) * (right - left)。指针移动规则每次移动高度较小的一侧指针因为容器的高度由短板决定移动高侧指针无法增加容积只有移动矮侧指针才有可能找到更高的短板从而增大容积。循环更新最大值每次计算当前面积与历史最大面积比较保留最大值直到两指针相遇。为什么双指针法正确初始时两指针间距最大是宽度最大的情况。每次舍弃较短的边保留较长的边不会错过最优解因为保留长边才有机会获得更大的容积。Java 代码实现java运行class Solution { public int maxArea(int[] height) { // 记录最大容积 int maxarea 0; // 左指针指向数组起始位置 int left 0; // 右指针指向数组末尾 int right height.length - 1; // 双指针未相遇时循环 while (left right) { // 计算当前容积宽度right-left高度左右指针较小值 int currentArea Math.min(height[left], height[right]) * (right - left); // 更新最大容积 maxarea Math.max(maxarea, currentArea); // 移动较小高度的指针寻找更大容积 if (height[left] height[right]) { left; } else { right--; } } return maxarea; } }代码详解变量定义maxarea存储遍历过程中找到的最大容积初始值为 0。left左指针初始为 0数组第一个元素。right右指针初始为height.length - 1数组最后一个元素。循环逻辑循环条件left right保证两指针不重叠至少有两条线才能构成容器。每次计算当前指针围成的容积用Math.max更新最大容积。比较左右指针的高度左高度小就右移左指针右高度小就左移右指针。返回结果循环结束后maxarea即为最大容积。复杂度分析时间复杂度O(n)只需要遍历一次数组双指针总共移动n次。空间复杂度O(1)仅使用了常数个额外变量没有开辟新的数组空间。测试用例用例 1输入[1,8,6,2,5,4,8,3,7]输出49用例 2输入[1,1]输出1用例 3输入[4,3,2,1,4]输出16总结这道题是双指针法的经典应用核心在于理解「容积由短板决定」通过移动短板指针贪心寻找最优解相比暴力枚举O(n2)效率大幅提升是面试高频考点。