每日算法之盛最多水的容器

130 阅读2分钟

原题链接

解决“容器装最多水”问题

介绍

在编程面试中,经常会遇到各种算法问题,其中“容器装最多水”是一个非常经典的问题。它不仅考察了基本的编程能力,还考察了对算法效率的考虑。本教程将使用JavaScript语言,通过双指针法详细解释如何解决这个问题。

问题描述

给定一个数组height,它的每个元素代表一个点的高度。你需要找出两个点,使得它们和x轴共同构成的容器可以容纳最多的水。注意:容器的容量是由x轴和两个点中较短的那个决定的。

思路分析

解决这个问题最直观的方法可能是遍历数组中所有可能的点对,计算它们构成的容器的容量,并记录最大值。然而,这种方法的时间复杂度为O(n^2),对于大数组来说效率非常低下。

更高效的方法是使用双指针法。具体思路如下:

  1. 初始化:将两个指针分别置于数组的起始位置和末尾位置,表示容器的两端。
  2. 遍历:在左指针小于右指针的条件下遍历数组。
  3. 计算并更新最大容量:对于每一对指针,计算它们能够构成的容器的容量,并更新最大容量。
  4. 移动指针:每次迭代中,移动两个指针中指向较短线段的那一个,因为我们希望找到可能更长的线段来增加容器的容量。

实现代码

function maxArea(height) {
    let left = 0; // 左指针
    let right = height.length - 1; // 右指针
    let maxArea = 0; // 最大面积初始化为0

    while (left < right) {
        // 计算当前的容量
        const currentArea = Math.min(height[left], height[right]) * (right - left);
        // 更新最大容量
        maxArea = Math.max(maxArea, currentArea);
        // 移动指针
        if (height[left] < height[right]) {
            left++;
        } else {
            right--;
        }
    }

    return maxArea;
}

代码解释

  • Math.min(height[left], height[right]) 确定容器的高度。
  • (right - left) 计算容器的宽度。
  • 我们在每次循环中计算当前指针对应的容器的面积,并与之前的最大面积比较,保留较大的一个。
  • 根据两个指针所指高度的比较结果,决定是移动左指针还是右指针。这一步是基于一个逻辑:容器的容量受到较短边的限制,所以我们希望找到可能更高的边来尝试增加容量。

总结

通过使用双指针法,我们可以将时间复杂度从O(n^2)降低到O(n),这对于处理大数据集非常有用。这种方法不仅适用于“容器装最多水”问题,还可以应用于其他需要双向搜索的场景。学会这种方法,对于提升解决问题的效率大有帮助。希望本教程能帮助你理解和掌握双指针法。