返回

解题攻略:水容量最大容器的盛水奥秘——LeetCode 11

后端

如何解决 LeetCode 11:盛最多水的容器

想象一下你在一个装满水的矩形空间中,由一系列柱形组成。你的目标是找到两个柱形,使它们之间形成一个容器,可以容纳最多的水。这个容量由这两个柱形之间的最小高度决定。准备踏上这段寻水之旅,我们将逐步揭开这个难题。

剖析问题

要找到盛水量最大的容器,我们首先需要了解问题的核心。容器的容量取决于两个柱形之间的最小高度。因此,我们需要遍历所有可能的柱形对,计算它们之间的最小高度,并据此计算容量。一旦我们计算出每个容器的容量,我们就可以确定盛水量最大的容器。

解题步骤

  1. 初始化指针: 我们将使用两个指针,一个指向数组的开头,另一个指向数组的末尾。这两个指针表示我们正在考虑的容器的左右边界。
  2. 计算容器容量: 对于给定的左右指针位置,我们计算容器的宽度(即两个指针之间的距离)和高度(即左右指针指向的柱形中较低的那个)。容器的容量是宽度乘以高度。
  3. 更新最大容量: 我们比较当前容器的容量与迄今为止找到的最大容量。如果当前容量更大,则更新最大容量。
  4. 移动指针: 为了继续探索所有可能的容器,我们需要移动指针。如果左指针指向的柱形高度较低,则我们将它向右移动。否则,我们将右指针向左移动。

代码示例

public class Solution {
    public int maxArea(int[] height) {
        int left = 0, right = height.length - 1;
        int maxArea = 0;
        while (left < right) {
            int minHeight = Math.min(height[left], height[right]);
            int area = minHeight * (right - left);
            maxArea = Math.max(maxArea, area);
            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
        return maxArea;
    }
}

实现细节

  1. 指针初始化: 我们从数组的开头和末尾开始,分别用 left 和 right 指针表示容器的左右边界。
  2. 容量计算: 对于给定的左右指针位置,我们计算容器的宽度(即 right - left)和高度(即 minHeight)。容量是宽度乘以高度。
  3. 最大容量更新: 我们比较当前容器的容量与迄今为止找到的最大容量。如果当前容量更大,则更新最大容量。
  4. 指针移动: 为了探索所有可能的容器,我们移动指针。如果 left 指针指向的柱形高度较低,则我们将其向右移动(left++)。否则,我们将 right 指针向左移动(right--)。

复杂度分析

  • 时间复杂度: O(n),其中 n 是数组的长度。
  • 空间复杂度: O(1),因为我们只使用了常数空间来存储变量。

总结

通过遍历所有可能的柱形对并计算它们之间的最小高度,我们可以找到盛水量最大的容器。本算法的时间复杂度为 O(n),空间复杂度为 O(1),使其成为解决 LeetCode 11 问题的有效方法。

常见问题解答

  1. 我可以在不使用指针的情况下解决这个问题吗?

    • 可以,但效率较低。你可以使用嵌套循环遍历所有可能的柱形对,但时间复杂度将为 O(n^2)。
  2. 算法可以扩展到三维空间吗?

    • 对于三维空间,我们可以使用类似的方法,但算法会更加复杂。一种方法是使用动态规划,时间复杂度为 O(n^3)。
  3. 如果柱形的高度不同,算法是否仍然有效?

    • 是的,算法仍然有效。它将找到由不同高度柱形形成的最大容量容器。
  4. 算法可以用来解决其他类似的问题吗?

    • 是的,这种方法可以推广到其他寻找最大面积或体积的问题,例如寻找直方图中的最大面积。
  5. 为什么算法的时间复杂度是 O(n)?

    • 由于两个指针始终向相反方向移动,因此每个柱形最多只会被访问一次。因此,总共需要 O(n) 次遍历。