当前位置: 首页 > news >正文

力扣(盛最多水的容器)

解析 LeetCode 11. 盛最多水的容器:双指针的巧妙运用

一、题目剖析

在这里插入图片描述

(一)问题描述

给定一个整数数组 height,数组中的每个元素代表坐标 (i, height[i]) 处垂直于 x 轴的线段高度。我们需要找出两条线段,与 x 轴构成一个容器,使得这个容器能容纳最多的水。容器的容量由较短的线段高度两条线段在 x 轴上的距离决定,公式为:容量 = min(高1, 高2) * 水平距离

(二)核心挑战

如何高效地遍历所有可能的线段组合,找到容量最大的那个,同时避免暴力枚举带来的高时间复杂度。如果采用暴力法,遍历所有两两组合,时间复杂度会达到 O(n2)O(n^2)O(n2) ,当 n 较大时,效率极低。所以需要更聪明的算法来优化。

二、算法思想:双指针的高效遍历

(一)双指针的选择逻辑

我们使用两个指针,分别从数组的两端开始left 指向开头,right 指向末尾 )。这样,初始时水平距离是最大的(为 n - 1n 是数组长度 )。接下来,通过移动指针来缩小范围,寻找更大的容量。

(二)指针移动的策略

容器的容量由较短的线段决定。因此:

  • height[left] < height[right] 时,说明当前容器的容量受限于 left 对应的线段高度。如果我们移动 right 指针(即选择更短的水平距离 ),由于 left 不变且是较短的一方,新的容量只会更小(因为水平距离减小,而高度由 left 决定,不会增加 )。所以此时应移动 left 指针,尝试寻找更高的 left 线段,以期望获得更大的容量。
  • 反之,当 height[right] <= height[left] 时,移动 right 指针,寻找更高的 right 线段,尝试提升容量。

这种指针移动策略,每次都舍弃“不可能带来更大容量”的那一侧,从而将时间复杂度优化到 O(n)O(n)O(n) ,只需遍历一次数组就能找到最大容量。

三、代码实现与深度解析

class Solution {public int maxArea(int[] height) {// 初始化左指针,指向数组开头int left = 0; // 初始化右指针,指向数组末尾int right = height.length - 1; // 存储最大容量,初始为 0int max = 0; // 双指针遍历,直到左指针超过右指针while (left < right) { // 计算当前容器的容量:短边高度 * 水平距离int currArea = Math.min(height[right], height[left]) * (right - left); // 更新最大容量max = Math.max(max, currArea); // 移动指针:哪边高度低,就移动哪边的指针,寻找更高的边if (height[right] > height[left]) { left++; } else { right--; }}return max; }
}

(一)代码执行流程

  1. 初始化left 指向数组起始位置(索引 0 ),right 指向数组末尾位置(索引 height.length - 1 ),max 初始化为 0 ,用于记录最大容量。
  2. 双指针遍历:进入 while 循环,只要 left < right ,就持续计算和比较:
    • 计算当前 leftright 对应的容器容量 currArea ,依据是短边高度乘以水平距离。
    • Math.max 函数,将 currAreamax 比较,更新 max 为较大值。
    • 根据 leftright 对应线段的高度,移动指针:若 height[right] > height[left] ,说明 left 是短边,移动 left 指针(left++ );否则移动 right 指针(right-- )。
  3. 返回结果:循环结束后,max 中存储的就是能盛最多水的容器容量,返回 max

(二)关键逻辑拆解

  • 容量计算Math.min(height[right], height[left]) 确定短边高度,(right - left) 是水平距离,两者相乘得到当前容器容量,这是容器容量计算的核心公式。
  • 指针移动决策:通过比较 height[left]height[right] 的大小,决定移动哪一侧的指针。这样的决策确保了每次移动都是在尝试提升容器的容量,因为舍弃短边,去寻找更长的边,才有可能获得更大的容量。
  • 时间复杂度优化:双指针只需遍历一次数组(O(n) ),相较于暴力法的 O(n^2) ,效率大幅提升,尤其在数组长度较大时优势明显。

四、复杂度分析

(一)时间复杂度

双指针从数组两端向中间遍历,每个元素最多被访问一次,所以时间复杂度为 O(n)O(n)O(n) ,其中 n 是数组 height 的长度。

(二)空间复杂度

代码中只使用了常数级别的额外变量(leftrightmaxcurrArea ),所以空间复杂度为 O(1)O(1)O(1)

http://www.dtcms.com/a/331167.html

相关文章:

  • Java基础 8.14
  • 力扣-5.最长回文子串
  • MySQL的索引(索引的创建和设计原则):
  • 初识c语言————缓冲区字符滞留
  • 天马 TM150XDHG01-04 宽温高亮液晶模组技术档案
  • **标题:发散创新,探索编程中的平衡设计****摘要**:本文将探讨如何在编程中运用平衡设计思想,通过实例分析与
  • STM32F103 basic定时器的介绍和应用
  • 2021-2025全国监测国控断面地表水水质数据
  • P12348 [蓝桥杯 2025 省 A 第二场] 交互
  • 每日任务day0814:小小勇者成长记之钓鱼日记(字典推导式)
  • gpt2架构学习(1)
  • PDM 如何通过 ERP/PLM 释放数据价值?
  • 力扣面试150(56/150)
  • CodeTop 复习
  • [免费]基于Python的影视数据可视化分析系统(Flask+echarts)【论文+源码+SQL脚本】
  • 实战指南|消防管理系统搭建全流程解析
  • Android 常用框架汇总
  • AI需要提供情绪价值吗?GPT-4o风波背后的安全与孤独之战
  • 云原生俱乐部-杂谈1
  • python爬虫学习(2)
  • vite.config.js详解;本地配置获取真实请求地址
  • mysql——count(*)、count(1)和count(字段)谁更快?有什么区别?
  • 《软件工程导论》实验报告三 需求分析建模(二)
  • SQL LEFT JOIN 与 WHERE 条件的隐藏坑
  • anaconda创建pytorch1.10.0和pytorch2.0.0的GPU环境
  • iOS 26 一键登录失效:三大运营商 SDK 无法正常获取手机号
  • 装个 Oracle 23ai 本地版玩玩~
  • 短剧小程序系统开发:赋能创作者,推动短剧艺术创新发展
  • SpringBoot+Vue线上部署MySQL问题解决
  • CPP模板编程