一、题目描述

二、解题思路

我们使用双指针法来高效解决这个问题:

  1. 使用左右指针分别指向数组的两端

  2. 计算当前指针位置能容纳的水量

  3. 移动高度较小的指针,因为移动高度较大的指针不会增加容量

  4. 持续更新最大水量直到指针相遇

三、完整代码

class Solution {
public:
    int maxArea(vector<int>& height) {
        int l = 0;
        int r = size(height) - 1;
        int maxarea = 0;
        while (l < r) {
            int curarea = min(height[l], height[r]) * (r - l);
            maxarea = max(curarea, maxarea);
            if (height[l] < height[r]) {
                l++;
            } else {
                r--;
            }
        }
        return maxarea;
    }
};

四、代码解析

1. 初始化指针

int l = 0;
int r = size(height) - 1;

  • 左指针 l 指向数组起始位置

  • 右指针 r 指向数组末尾位置

2. 计算当前面积

int curarea = min(height[l], height[r]) * (r - l);

  • 容器高度由较短的垂线决定:min(height[l], height[r])

  • 容器宽度为两指针距离:(r - l)

  • 当前面积 = 高度 × 宽度

3. 更新最大面积

maxarea = max(curarea, maxarea);

  • 比较当前面积与历史最大面积

  • 保留较大的值

4. 移动指针

if (height[l] < height[r]) {
    l++;
} else {
    r--;
}

  • 关键策略:移动高度较小的指针

  • 因为移动高度较大的指针不会增加最小高度,而宽度在减少,总面积必然减少

五、语法要点

1. 双指针技巧

int l = 0;                    // 左指针初始化
int r = size(arr) - 1;        // 右指针初始化
while (l < r) {              // 循环条件
    // 处理逻辑
    l++或r--;                 // 指针移动
}

2. 容器操作

size(arr);    // 获取数组/容器的大小

六、执行示例

输入:[1,8,6,2,5,4,8,3,7]

执行过程:

  1. l=0, r=8 → 高度min(1,7)=1, 宽度=8 → 面积=8

  2. 移动左指针(l=1), r=8 → 高度min(8,7)=7, 宽度=7 → 面积=49

  3. 移动右指针(l=1), r=7 → 高度min(8,3)=3, 宽度=6 → 面积=18

  4. 继续移动指针...

  5. 最终找到最大面积:49

最终结果:49


总结

        本文介绍了使用双指针法解决容器盛水问题的算法。通过从数组两端向中间移动指针,并始终移动高度较小的指针,我们能够在O(n)时间复杂度内找到最大盛水面积。算法的关键在于理解移动较高指针不会改善结果,而移动较低指针可能找到更高的边界,从而可能获得更大的面积。这种方法高效且直观,是双指针技巧的经典应用。

更多推荐