每日一题——盛水最多的容器

建议参考下面视频

题目描述

给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度。请问从中选2个高度与x轴组成的容器最多能容纳多少水。
在这里插入图片描述

约束条件

  1. 不能倾斜容器
  2. 当n小于2时,视为不能形成容器,返回0
  3. 容纳的水量不会超过整形范围(231-1)

数据范围

  • 0 <= height.length <= 105
  • 0 <= height[i] <= 104

解题思路

方法:双指针法

这道题可以使用双指针的方法来解决。基本思路是:

  1. 使用两个指针left和right,初始分别指向数组的左右两端
  2. 计算当前两个指针位置可以容纳的水量
  3. 移动较小高度的指针(因为移动较大的高度不可能得到更大的面积)
  4. 重复步骤2-3直到两个指针相遇

时间复杂度分析

  • 时间复杂度:O(n) - 每个指针最多移动n次
  • 空间复杂度:O(1) - 只使用常数额外空间

代码实现

int maxArea(int* height, int heightLen) {
    // 初始化变量:
    // max:用于存储最大面积
    // left:左指针,初始指向数组的第一个元素
    // right:右指针,初始指向数组的最后一个元素
    int max = 0;
    int left = 0;
    int right = heightLen - 1;

    // 当左指针小于右指针时,继续循环
    while (left < right) {
        // 计算当前左右指针之间的面积:
        // 面积 = 宽度 × 较短的高度
        // 宽度为左右指针的索引差 (right - left)
        // 较短的高度为 height[left] 和 height[right] 中的较小值
        int temp = (right - left) * (height[left] > height[right] ? height[right] : height[left]);

        // 更新最大面积:
        // 如果当前面积 temp 大于之前的最大面积 max,则更新 max
        max = max > temp ? max : temp;

        // 移动指针:
        // 为了寻找更大的面积,需要移动较短高度的指针,因为移动较长高度的指针无法增加面积
        if (height[left] > height[right]) {
            // 如果左高度大于右高度,移动右指针:
            // 记录当前右高度
            int cur = height[right];
            // 移动右指针,直到找到比当前右高度更高的柱子
            while (left < right && height[right] <= cur)
                right--;
        } else {
            // 如果右高度大于或等于左高度,移动左指针:
            // 记录当前左高度
            int cur = height[left];
            // 移动左指针,直到找到比当前左高度更高的柱子
            while (left < right && height[left] <= cur)
                left++;
        }
    }

    // 返回最终的最大面积
    return max;
}

示例分析

示例1

输入:[1,7,3,2,4,5,8,2,7]
返回值:49

示例2

输入:[2,2]
返回值:2

示例3

输入:[5,4,3,2,1,5]
返回值:25

解题技巧

  1. 初始化指针:将左指针指向数组开头,右指针指向数组末尾。

  2. 计算面积:面积 = 两指针之间的距离 × 较小的高度。

  3. 指针移动策略

    • 始终移动较小高度的指针
    • 如果高度相等,可以移动任意一个指针
    • 移动时可以跳过不可能产生更大面积的位置
  4. 优化技巧

    • 使用while循环跳过相同高度的位置
    • 及时更新最大面积

常见错误

  1. 忘记处理数组长度小于2的边界情况
  2. 面积计算公式错误
  3. 指针移动策略不当
  4. 没有正确处理相等高度的情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tt555555555555

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值