【LeetCode 热题 100】11. 盛最多水的容器——Java双指针解法

11. 盛最多水的容器

整体思路

这段代码采用了双指针(Two-Pointers) 的优化算法来解决"盛最多水的容器"问题。与暴力枚举所有可能性的 O(n²) 方法不同,双指针法通过一种更智能的收缩策略,仅需一次遍历即可找到最大面积,效率极高。

其整体思路如下:

  1. 初始化指针 :算法设置两个指针,left 指向数组的第一个元素(索引 0),right 指向数组的最后一个元素(索引 n-1)。这两个指针代表了当前考虑的容器的左右两个边界。这个初始状态构成了宽度最大的容器。

  2. 迭代收缩 :指针 leftright 在一个 while 循环中相向移动,直到它们相遇(left >= right)。在每次循环中,执行以下操作:

    • 计算当前面积 :容器的宽度是 w = right - left,高度 h 则由两个边界中较短的那条线决定,即 h = Math.min(height[left], height[right])。当前容器的面积就是 area = w * h
    • 更新最大面积 :将当前计算出的 area 与全局最大面积 ans 进行比较,并始终保留较大者。
  3. 指针移动策略(核心) :这是算法的关键所在。在计算完当前面积后,需要决定移动哪个指针(left 还是 right)来寻找下一个可能的更大容器。

    • 当前面积受限于宽度高度 。由于指针在相向移动,宽度 w 在后续的迭代中只会减小,不会增大
    • 因此,要想找到一个更大的面积,唯一的希望就是增加容器的高度 h
    • 容器的高度 hheight[left]height[right] 中的短板决定。如果移动长板那一侧的指针,短板依然是那个短板,高度 h 不会增加(甚至可能减小),而宽度 w 又减小了,所以面积必然不会变大。
    • 结论是:必须移动指向短板的那个指针。因为只有移动短板,才有可能在下一次迭代中遇到一个更高的板,从而增加容器的整体高度,弥补宽度减小的损失,进而才有可能找到更大的面积。
  4. 返回结果 :当 while 循环结束时(leftright 相遇),意味着所有具有潜力的容器都已被考虑过。此时 ans 中存储的就是最终的最大面积。

完整代码

java 复制代码
class Solution {
    public int maxArea(int[] height) {
        // ans 用于存储并更新找到的最大面积,初始化为0。
        int ans = 0;
        // 初始化左指针,指向数组的起始位置。
        int left = 0;
        // 初始化右指针,指向数组的末尾位置。
        int right = height.length - 1;

        // 当左指针在右指针左侧时,持续循环。
        // 这是双指针算法的核心循环结构。
        while (left < right) {
            // 计算当前容器的宽度,即两个指针之间的距离。
            int w = right - left;
            // 计算当前容器的高度,由左右两条线中较短的一条决定。
            int h = Math.min(height[left], height[right]);
            // 计算当前容器的面积。
            int area = w * h;
            // 将当前面积与已知的最大面积比较,并更新最大面积。
            ans = Math.max(ans, area);

            // --- 核心移动逻辑 ---
            // 如果左边的线比右边的线短。
            if (height[left] < height[right]) {
                // 移动左指针向右。因为移动短板才有可能找到更高的板,从而可能获得更大的面积。
                left++;
            } else {
                // 如果右边的线比左边的线短,或者两者一样高。
                // 移动右指针向左。
                right--;
            }
        }
        
        // 循环结束后,ans 中保存的就是最终的最大面积。
        return ans;
    }
}

时空复杂度

时间复杂度:O(n)
  1. 分析依据 :算法使用 leftright 两个指针。left0 开始向右移动,rightn-1 开始向左移动。
  2. while 循环的每一次迭代中,要么 left 加一,要么 right 减一,两个指针之间的距离 right - left 至少会减少1。
  3. 两个指针只会相向移动,绝不会后退或停滞。它们从数组的两端开始,直到相遇为止。
  4. 因此,两个指针总共会移动 n-1 步。这意味着循环体内的操作最多执行 n-1 次。

结论 :算法的执行时间与输入数组的规模 n 呈线性关系,因此时间复杂度为 O(n)

空间复杂度:O(1)
  1. 分析依据 :算法在执行过程中,除了输入数组 height 本身占用的空间外,只使用了有限几个变量(ans, left, right, w, h, area)。
  2. 这些变量的数量是固定的,不随输入数组 height 的大小 n 的增加而增加。
  3. 没有创建任何新的、大小与 n 相关的辅助数据结构(如额外的数组、哈希表等)。

结论 :算法所需的额外存储空间是常数级别的,因此空间复杂度为 O(1)

相关推荐
拾忆,想起13 分钟前
RabbitMQ事务机制深度剖析:消息零丢失的终极武器
java·开发语言·分布式·后端·rabbitmq·ruby
李贺梖梖16 分钟前
DAY22 XML、XML解析
java
梵得儿SHI21 分钟前
Java 操作 XML 及动态生成报告:从解析到实战
xml·java·jaxb·dom4j·xml解析·操作xml·报告生成
CHANG_THE_WORLD21 分钟前
函数简单传入参数的汇编分析
汇编·c++·算法
安全风信子28 分钟前
45_混合专家模型:MoE架构详解
算法
ASIAZXO35 分钟前
机器学习——聚类kmeans算法详解
算法·机器学习·聚类
Terio_my44 分钟前
Spring Boot 热部署配置与禁用
java·spring boot·后端
青云交1 小时前
Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频语义理解与智能检索进阶
java·深度学习·监控系统·行为识别·智能安防·智能检索·视频语义理解
!chen1 小时前
如何在新的Spring Boot项目中关闭Spring Security?
java·spring·jar
我是华为OD~HR~栗栗呀2 小时前
Java面经(22届考研-华oD)
java·后端·python·华为od·华为