当前位置: 首页 > article >正文

33-盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

方法一:暴力枚举法

该方法通过遍历数组中所有可能的两条线的组合,计算它们所构成容器的水量,然后找出其中的最大值。

function maxArea(height: number[]): number {
    let maxWater = 0;
    const n = height.length;
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            const width = j - i;
            const minHeight = Math.min(height[i], height[j]);
            const water = width * minHeight;
            maxWater = Math.max(maxWater, water);
        }
    }
    return maxWater;
}
复杂度分析
  • 时间复杂度:(O(n^2)),因为需要使用两层嵌套循环来遍历所有可能的线对,n 是数组的长度。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间来存储最大水量。

方法二:双指针法

使用两个指针分别指向数组的首尾,计算当前指针所指两条线构成的容器水量,然后根据两条线的高度,移动较短的线对应的指针,继续计算水量,直到两个指针相遇。

function maxArea(height: number[]): number {
    let left = 0;
    let right = height.length - 1;
    let maxWater = 0;

    while (left < right) {
        const width = right - left;
        const minHeight = Math.min(height[left], height[right]);
        const water = width * minHeight;
        maxWater = Math.max(maxWater, water);

        if (height[left] < height[right]) {
            left++;
        } else {
            right--;
        }
    }

    return maxWater;
}
复杂度分析
  • 时间复杂度:(O(n)),只需要遍历数组一次,n 是数组的长度。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间来存储指针和最大水量。

方法三:优化双指针法(提前终止部分计算)

在双指针法的基础上,当移动指针时,如果新的指针所指的线高度小于等于之前的线高度,那么可以直接跳过,因为这样构成的容器水量不会更大。

function maxArea(height: number[]): number {
    let left = 0;
    let right = height.length - 1;
    let maxWater = 0;

    while (left < right) {
        const width = right - left;
        const minHeight = Math.min(height[left], height[right]);
        const water = width * minHeight;
        maxWater = Math.max(maxWater, water);

        if (height[left] < height[right]) {
            const currentLeftHeight = height[left];
            while (left < right && height[left] <= currentLeftHeight) {
                left++;
            }
        } else {
            const currentRightHeight = height[right];
            while (left < right && height[right] <= currentRightHeight) {
                right--;
            }
        }
    }

    return maxWater;
}
复杂度分析
  • 时间复杂度:\(O(n)\),虽然增加了一些内部的指针移动判断,但总体上仍然只需要遍历数组一次,n 是数组的长度。
  • 空间复杂度:\(O(1)\),只使用了常数级的额外空间来存储指针和最大水量。

你可以使用以下方式测试这些函数:

const height = [1, 8, 6, 2, 5, 4, 8, 3, 7];
console.log(maxArea(height));

综上所述,双指针法及其优化版本是解决该问题的高效方法,时间复杂度较低。

 


http://www.kler.cn/a/593813.html

相关文章:

  • 华为云-图像识别API服务调用
  • 报错:URI malformed at decodeURIComponent
  • Python搭建项目独立环境
  • 高温工厂降温如何有效实现?
  • Lineageos 22.1(Android 15)应用双开
  • Spring Boot中定时任务Cron表达式的终极指南
  • DeepSeek|优化prompt设计有哪些方法?
  • 如何在 Github 上获得 1000 star?
  • 深入理解 C++20 中的 `std::shared_ptr` 原子操作
  • BigInteger 的常用函数分类说明
  • 23种设计模式中的状态模式
  • vue-tsc 使用问题及解决方法
  • 鸿蒙Next开发与未来发展的变革:全场景操作系统的全新纪元
  • Linux内核IPv4路由选择子系统
  • 汇川EASY系列之以太网通讯(MODBUS_TCP做从站)
  • MySQL:数据库基础
  • HTML5学习成果(仅HTML部分)
  • 无需qt-creator,使用Trae从0到1生成qt的开发、构建、调试环境
  • 网络安全常识科普(百问百答)
  • 游戏引擎学习第169天