DAILY DOCDAILY DOC
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
  • Array

    • 数组
    • 二分查找
    • moveZeros
  • Dynamic-programming

    • 动态规划
  • 刷题指南
  • String

    • 字符串
  • bitwise-operator

    • 位运算符
  • heap
  • history

    • [1014] 最佳观光组合
    • [1022] 从根到叶的二进制数之和
    • [104] 二叉树的最大深度
    • [11] 盛最多水的容器
    • [110] 平衡二叉树
    • [1227] 飞机座位分配概率
    • [129] 求根节点到叶节点数字之和
    • [1306] 跳跃游戏 III
    • [148] 排序链表
    • 155.最小栈
    • [165] 比较版本号
    • 1763. 最长的美好子字符串
    • [1870] 准时到达的列车最小时速
    • [199] 二叉树的右视图
    • [21] 合并两个有序链表
    • 215.数组中的第 k 个最大元素
    • [2306] 公司命名
    • [234] 回文链表
    • [2516] 每种字符至少取 K 个
    • [316] 去除重复字母
    • [3171] 找到按位或最接近 K 的子数组
    • [322] 零钱兑换
    • [41] 缺失的第一个正数
    • [44] 通配符匹配
    • [494] 目标和
    • [509] 斐波那契数
    • [518] 零钱兑换 II
    • [62] 不同路径
    • [676] 实现一个魔法字典
    • 70 爬楼梯
    • [718] 最长重复子数组
    • [78] 子集
    • [82] 删除排序链表中的重复元素 II
    • [871] 最低加油次数
    • [88] 合并两个有序数组
    • [887] 鸡蛋掉落
    • 958.二叉树的完全性检验
    • [98] 验证二叉搜索树
    • [983] 最低票价
    • leetcode practice
    • 约瑟夫问题
    • 移除重复节点
  • linked-list

    • 706. 设计哈希映射
    • 链表
  • stack

    • stack
  • tree

    • Tree Traversal
    • 二叉树的最近公共祖先
    • 二叉树
    • 题目
  • leetCode 刷题
  • 回溯
  • 排序算法

[11] 盛最多水的容器

双指针

details

解题思路

要最大化容器能够盛水的面积,面积公式为: [ \text{Area} = \text{min}(height[i], height[j]) \times (j - i) ]

其中,i 和 j 是数组 height 中两条垂直线的索引。要找到能容纳最多水的两条线,我们可以使用 双指针 技巧:

  1. 初始化左右指针:分别指向数组的最左端和最右端,即 i = 0 和 j = height.length - 1。
  2. 计算当前面积:使用公式计算当前左右指针对应的面积。
  3. 移动指针:移动较短的那条线的指针。因为容器的面积取决于较短的那条线,高度更小的那一边无法形成更大的面积,因此我们尝试移动它来寻找可能更大的容器。
  4. 重复上述步骤,直到两个指针相遇为止,过程中记录最大面积。

代码实现(双指针法)

function maxArea(height) {
    let left = 0; // 左指针
    let right = height.length - 1; // 右指针
    let maxArea = 0; // 初始化最大面积

    while (left < right) {
        // 计算当前左右指针构成的容器的面积
        let currentArea = Math.min(height[left], height[right]) * (right - left);
        maxArea = Math.max(maxArea, currentArea); // 更新最大面积

        // 移动较短的一边,寻找可能的更大面积
        if (height[left] < height[right]) {
            left++; // 左边较短,移动左指针
        } else {
            right--; // 右边较短,移动右指针
        }
    }

    return maxArea; // 返回最大面积
}

代码解释:

  • 初始化指针:left 指向数组的开头,right 指向数组的末尾。
  • 循环:每次计算由 left 和 right 形成的容器面积,并将其与当前最大面积比较。
  • 移动指针:总是移动较短的一边,因为移动较长的一边不会增加面积。
  • 终止条件:当 left 和 right 指针相遇时,遍历结束,返回最大面积。

时间复杂度分析:

  • 每次迭代我们都在做常数时间的运算并移动指针,因此时间复杂度为 (O(n)),其中 (n) 是数组的长度。
  • 空间复杂度为 (O(1)),因为只使用了常数空间来存储指针和面积。

示例

对于输入 height = [1,8,6,2,5,4,8,3,7],执行过程如下:

  • 初始时,left = 0,right = 8,对应的容器面积为 min(1, 7) * 8 = 8。
  • 因为左边较短,移动左指针,left = 1。
  • 计算新的面积 min(8, 7) * 7 = 49,更新最大面积。
  • 移动右指针,重复此过程,最终找到最大面积为 49。

这个解法有效地减少了时间复杂度,避免了暴力枚举所有可能的线对。

Last Updated:
Contributors: rosendo
Prev
[104] 二叉树的最大深度
Next
[110] 平衡二叉树