LeetCode 第11题:盛最多水的容器

本文详细解析LeetCode第11题,盛最多水的容器问题,采用双指针法求解,通过步骤详解、动图演示、代码实现和举例说明,帮助理解算法思想。
摘要由CSDN通过智能技术生成

本文我们来讲解LeetCode 第11题:盛最多水的容器 —— 详解与实现。

引言

大家好!今天咱们要讨论的是LeetCode上的第11题——盛最多水的容器。这个题目表面看起来就像是个简单的几何问题,但实际上却蕴含着许多算法上的奥妙。接下来,我将带你一起揭开这个问题的神秘面纱。

题目描述

题目要求给定一个数组 height,其中每个元素表示一条垂直的线段的高度。每条线段的宽度是1。我们需要找出两条线段,使得它们与x轴一起形成的容器可以容纳最多的水。
说明:你不能倾斜容器。

示例 1:
盛最多水的容器

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:

输入:height = [1,1]
输出:1

思路解析

要解这个题,咱们得动点脑筋。显然,光用暴力破解法是行不通的,咱们得想点聪明的办法。于是,“双指针”大法便横空出世了。

双指针解法

步骤详解

  1. 初始化两个指针:一个指向数组的开头(left),一个指向数组的末尾(right)。
  2. 计算当前容器的容量:用两个指针指向的高度的较小值乘以它们之间的距离。
  3. 移动指针:为了找到可能更大的容器,我们需要移动指针。移动哪个指针呢?当然是移动较矮的那个指针,这样才有可能找到一个更高的线段,增加容量。
  4. 重复以上步骤,直到两个指针相遇。

动图演示

Left Right 初始位置 移动较矮的指针 计算当前容量 loop [直到指针相遇] 最终容量 Left Right

代码实现

讲了这么多,咱们用Java代码实现一下:

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

代码详解

我们逐行来看一下代码的实现逻辑:

  1. 初始化变量

    int left = 0;
    int right = height.length - 1;
    int maxArea = 0;
    
    • left 初始化为0,指向数组的第一个元素。
    • right 初始化为 height.length - 1,指向数组的最后一个元素。
    • maxArea 初始化为0,用于记录最大面积。
  2. 循环计算面积

    while (left < right) {
        int minHeight = Math.min(height[left], height[right]);
        int width = right - left;
        int currentArea = minHeight * width;
        maxArea = Math.max(maxArea, currentArea);
    
    • 使用 while (left < right) 循环,直到两个指针相遇。
    • minHeight 计算当前指针所指高度的最小值。
    • width 计算两个指针之间的宽度。
    • currentArea 计算当前的容器面积。
    • 使用 Math.max 更新最大面积 maxArea
  3. 移动指针

    if (height[left] < height[right]) {
        left++;
    } else {
        right--;
    }
    
    • 如果 left 指针的高度小于 right 指针的高度,移动 left 指针。
    • 否则,移动 right 指针。

举例说明

咱们用几个例子来看看这个算法是怎么工作的:

  1. 示例1

    • 输入:[1,8,6,2,5,4,8,3,7]
    • 过程:
      • 初始指针:left = 0right = 8,面积 min(1,7) * (8-0) = 7 * 8 = 49
      • 移动 left,因为 1 < 7,面积变为 min(8,7) * (8-1) = 7 * 7 = 49
      • 继续移动 right,面积变为 min(8,3) * (7-1) = 3 * 6 = 18
      • ……(省略中间过程)
      • 最终得到最大面积为49。
  2. 示例2

    • 输入:[4,3,2,1,4]
    • 过程:
      • 初始指针:left = 0right = 4,面积 min(4,4) * (4-0) = 4 * 4 = 16
      • 移动 right,面积变为 min(4,1) * (3-0) = 1 * 3 = 3
      • 继续移动 right,面积变为 min(4,2) * (2-0) = 2 * 2 = 4
      • ……(省略中间过程)
      • 最终得到最大面积为16。
  3. 示例3

    • 输入:[1,2,1]
    • 过程:
      • 初始指针:left = 0right = 2,面积 min(1,1) * (2-0) = 1 * 2 = 2
      • 移动 right,面积变为 min(1,2) * (1-0) = 1 * 1 = 1
      • 最终得到最大面积为2。

总结

我们通过双指针的方法解决了盛最多水的容器问题。这种方法不仅简洁高效,而且通过移动指针来不断逼近最优解,避免了暴力破解的低效。希望这篇博客能够帮助大家更好地理解和掌握这道题目。下次遇到类似的问题时,别忘了用双指针大法来试试看哦!

如果本文对您有所帮助的话,请收藏文章、关注作者、订阅专栏,感激不尽。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gemini技术窝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值