【LeetCode】11. 盛最多水的容器

leetcode

 

解题思路

盛最多水容器问题的核心在于双指针法的应用。该方法的思路如下:

  1. 双指针初始化:左右指针分别指向数组两端,初始宽度最大。
  2. 贪心策略:每次移动较矮的指针(木桶效应),因为移动较高的指针无法增加容量。
  3. 动态更新:计算当前指针范围内的水量,并维护全局最大值。

关键步骤

  1. 初始化指针left=0right=len(height)-1
  2. 循环收缩:计算当前水量 min(height[left], height[right]) * (right-left)
  3. 指针移动:较矮的一侧向内移动,直到指针相遇。

Golang代码实现

func maxArea(height []int) int {
    left, right := 0, len(height)-1
    maxWater := 0

    for left < right {
        // 计算当前水量(木桶效应,取较矮的柱子)
        currentHeight := min(height[left], height[right])
        currentWidth := right - left
        currentWater := currentHeight * currentWidth

        // 更新最大水量
        if currentWater > maxWater {
            maxWater = currentWater
        }

        // 移动较矮的指针(贪心策略)
        if height[left] < height[right] {
            left++
        } else {
            right--
        }
    }
    return maxWater
}

// 辅助函数:取较小值
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

复杂度分析

指标说明
时间复杂度 O(n) 单次遍历数组,指针移动总次数为 n-1
空间复杂度 O(1) 仅需常数级变量

运行示例验证

func main() {
    // 示例1
    height1 := []int{1, 8, 6, 2, 5, 4, 8, 3, 7}
    fmt.Println(maxArea(height1)) // 输出: 49

    // 示例2
    height2 := []int{1, 1}
    fmt.Println(maxArea(height2)) // 输出: 1
}

核心逻辑说明

  1. 双指针策略

    • 初始时,左右指针分别指向数组两端,宽度最大(width = len(height)-1)。
    • 每次计算水量后,移动较矮的指针(如左指针指向的柱子高度为1,右指针指向的柱子高度为7,则移动左指针)。
    • 通过贪心策略,逐步缩小搜索范围,确保不漏掉可能的更大容量。
  2. 水量计算原理
    水量公式为 min(height[left], height[right]) * (right - left),其中:

    • 较矮柱子决定高度:容器的高度受限于较矮的柱子(木桶效应)。
    • 宽度逐步减少:指针移动时宽度减少,但可能通过找到更高的柱子弥补损失。
  3. 边界处理

    • 当数组长度为2时直接计算(如示例2)。
    • 无需处理空数组或单元素数组(题目保证 n >= 2)。

算法正确性证明

假设最大水量对应的柱子为 i 和 ji < j)。双指针法会通过以下步骤覆盖所有可能的候选解:

  1. 初始状态:左指针在0,右指针在 n-1
  2. 指针移动:若左指针先到达 i,则右指针会逐步左移至 j;若右指针先到达 j,左指针会逐步右移至 i
  3. 水量更新:每次移动较矮指针时,确保不会错过更高柱子的可能性。

扩展讨论

  1. 暴力法的局限性
    暴力法需要遍历所有组合(时间复杂度 O(n²)),在 n=1e5 时会超时,而双指针法的时间复杂度为 O(n),适用于大规模数据。

  2. 数学规律优化
    可通过提前终止循环优化性能(如当前最大水量已超过剩余宽度的潜在可能),但实现复杂且收益有限。


通过双指针法,该实现以最优时间和空间复杂度解决了问题,完美覆盖所有测试用例。

posted @ 2025-03-29 12:50  云隙之间  阅读(33)  评论(0)    收藏  举报