当前位置: 面试刷题>> 盛最多水的容器(经典算法150题)


题目描述

给定 n 个非负整数 a1, a2, ..., an,每个数代表坐标中的一个点 (i, ai)。在坐标内画 n 条垂直线,使得第 i 条线过点 (i, ai)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

注意:你不能倾斜容器,且 n 至少为 2。

示例

给定数组 [1,8,6,2,5,4,8,3,7],在这个例子中,垂直线分别表示为数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能容纳水最多的组合是高度为 1 和 8 的两个垂直线(即位于索引 0 和索引 1 的两个点),此时容器的面积为 (8 - 1) * min(1, 8) = 7 * 1 = 7

解题思路

这个问题可以使用双指针法来解决。初始化两个指针,一个指向数组的开始位置,另一个指向数组的结束位置。计算当前两个指针所指向的垂直线构成的容器的面积,并更新最大面积。然后,移动高度较小的那个指针向中间移动(因为移动高度较大的指针不会增加容器的面积,反而可能减小),继续计算并更新最大面积,直到两个指针相遇。

PHP 代码示例

function maxArea($height) {
    $maxArea = 0;
    $left = 0;
    $right = count($height) - 1;

    while ($left < $right) {
        $area = min($height[$left], $height[$right]) * ($right - $left);
        $maxArea = max($maxArea, $area);

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

    return $maxArea;
}

// 示例
$height = [1,8,6,2,5,4,8,3,7];
echo maxArea($height); // 输出 49

Python 代码示例

def maxArea(height):
    max_area = 0
    left, right = 0, len(height) - 1

    while left < right:
        area = min(height[left], height[right]) * (right - left)
        max_area = max(max_area, area)

        if height[left] < height[right]:
            left += 1
        else:
            right -= 1

    return max_area

# 示例
height = [1,8,6,2,5,4,8,3,7]
print(maxArea(height))  # 输出 49

JavaScript 代码示例

function maxArea(height) {
    let maxArea = 0;
    let left = 0;
    let right = height.length - 1;

    while (left < right) {
        const area = Math.min(height[left], height[right]) * (right - left);
        maxArea = Math.max(maxArea, area);

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

    return maxArea;
}

// 示例
const height = [1,8,6,2,5,4,8,3,7];
console.log(maxArea(height)); // 输出 49

以上代码示例均实现了盛最多水的容器的算法,并给出了示例输入和输出。希望这能帮助你理解并解答这个问题。

推荐面试题