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

【LeetCode 热题 100】盛最多水的容器


精选专栏链接 🔗


  • LeetCode hot 100系列专栏
  • MySQL技术笔记专栏
  • Redis技术笔记专栏
  • 消息中间件专栏
  • 大模型搭建专栏
  • Python学习笔记专栏
  • 深度学习算法专栏

欢迎订阅,点赞+关注,每日精进1%,与百万开发者共攀技术珠峰

更多内容持续更新中~



【LeetCode 热题 100】盛最多水的容器

  • 📝题目描述
  • 💡提示信息
  • 核心分析:面积如何计算?
  • 解法一:暴力枚举法
  • 解法二:双指针法(最优解)
    • 为什么移动较短的那根柱子?(数学证明)
  • 总结

📝题目描述

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 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

💡提示信息

  • n == height.length;
  • 2 <= n <=10 5 10^5105
  • 0 <= height[i] <=10 4 10^4104

核心分析:面积如何计算?

我们要找的是最大面积。假设我们选择了两条线,索引分别为i iij jj(假设i < j i < ji<j),它们的高度分别为h e i g h t [ i ] height[i]height[i]h e i g h t [ j ] height[j]height[j]

容器的面积公式为:
A r e a = 宽度 × 高度 Area = \text{宽度} \times \text{高度}Area=宽度×高度
A r e a = ( j − i ) × min ⁡ ( h e i g h t [ i ] , h e i g h t [ j ] ) Area = (j - i) \times \min(height[i], height[j])Area=(ji)×min(height[i],height[j])

这意味着,容器的盛水量取决于两个因素:

  • 底边的宽度:两根柱子的距离;
  • 短板的高度:两根柱子中较短的那一根(木桶效应);

解法一:暴力枚举法

暴力枚举法是最直观的思路是,需要尝试所有的组合:

  • 外层循环从第 1 根柱子开始;
  • 内层循环遍历该柱子后面的所有柱子;
  • 计算每一对组合的面积,并更新最大值;

Java 代码实现

classSolution{publicintmaxArea(int[]height){intmaxArea=0;for(inti=0;i<height.length;i++){for(intj=i+1;j<height.length;j++){intwidth=j-i;inth=Math.min(height[i],height[j]);maxArea=Math.max(maxArea,width*h);}}returnmaxArea;}}

提交代码,运行结果如下:

  • 时间复杂度:O ( N 2 ) O(N^2)O(N2)。我们需要计算N ( N − 1 ) / 2 N(N-1)/2N(N1)/2对组合;
  • 空间复杂度:O ( 1 ) O(1)O(1)

此方式逻辑上行得通,但是数组很大时,此方法会超时,因此不推荐使用,更推荐使用双指针法实现。


解法二:双指针法(最优解)

为了优化时间复杂度,我们需要一种更聪明的方法来排除不必要的计算。这就是双指针法

算法思路

  1. 初始化两个指针:left指向数组头部(0),right指向数组尾部(n-1)。此时宽度最大;
  2. 计算当前leftright围成的面积,并更新最大面积;
  3. 关键步骤:移动指针。(移动较短的柱子
    • 如果height[left] < height[right],则移动leftleft++)。
    • 如果height[left] >= height[right],则移动rightright--)。
  4. 重复步骤 2 和 3,直到leftright相遇。

为什么移动较短的那根柱子?(数学证明)

这是本题最难理解也最精彩的地方。假设当前height[left] < height[right]。此时面积S = h e i g h t [ l e f t ] × ( r i g h t − l e f t ) S = height[left] \times (right - left)S=height[left]×(rightleft)

如果我们移动较高的柱子(即right--):

  • 宽度( r i g h t − l e f t ) (right - left)(rightleft)必然减小;
  • 高度取决于min ⁡ ( h e i g h t [ l e f t ] , h e i g h t [ n e w _ r i g h t ] ) \min(height[left], height[new\_right])min(height[left],height[new_right])因为高度受限于较短的 height[left],无论 new_right多高,最终使用的高度都不可能超过 height[left]。
  • 结论:移动较高的柱子时,宽度变小,高度不变或变小→ \rightarrow面积一定变小

反之,如果我们移动较短的柱子(即left++):

  • 宽度( r i g h t − l e f t ) (right - left)(rightleft)必然减小;
  • 但是,新的高度height[new_left]可能会比原来的height[left]更高,从而可能抵消宽度的损失,甚至获得更大的面积。

一句话总结:只有移动短板,才有可能在宽度减小的情况下,通过增加高度来获得更大的面积。

Java 代码实现如下:

publicclassSolution{publicintmaxArea(int[]height){intleft=0;intright=height.length-1;intmaxArea=0;while(left<right){// 计算当前面积// 宽度是 right - left// 高度取两者的较小值intcurrentArea=Math.min(height[left],height[right])*(right-left);// 更新最大面积maxArea=Math.max(maxArea,currentArea);// 移动指针策略:谁短移谁if(height[left]<height[right]){left++;}else{right--;}}returnmaxArea;}}

运行结果如下:

进一步优化代码:

classSolution{publicintmaxArea(int[]height){intmax=0;// 使用局部变量缓存数组长度intlen=height.length;// 双指针intleft=0;intright=len-1;while(left<right){// 1. 缓存当前高度,避免重复访问数组inthLeft=height[left];inthRight=height[right];// 2. 计算宽度intwidth=right-left;// 3. 计算高度和移动指针if(hLeft<hRight){// 左边矮,用左边算面积,左指针右移// 三元运算符替换原有 Math.min/Math.maxintarea=hLeft*width;max=area>max?area:max;left++;}else{// 右边矮(或相等),用右边算面积,右指针左移intarea=hRight*width;if(area>max)max=area;right--;}}returnmax;}}

提交代码,运行结果如下:

复杂度分析

  • 时间复杂度:O ( N ) O(N)O(N)。双指针从两端向中间遍历,每个元素最多被访问一次。
  • 空间复杂度:O ( 1 ) O(1)O(1)。只需要常数级别的额外空间存储指针和最大面积。

总结

  • 暴力法虽然简单,但在大数据量下不可行;
  • 双指针法利用了“短板效应”这一特性,通过每次移动短板的策略,成功将O ( N 2 ) O(N^2)O(N2)优化到了O ( N ) O(N)O(N)

希望这篇解析能帮你彻底掌握这道题!Happy Coding! 🚀

http://www.rkmt.cn/news/1415662.html

相关文章:

  • 2026 彩屏智能开关怎么选:权威攻略最新解读 - 思溯深度专栏
  • 2026 郑州黄金回收避坑指南:商家实测与资质检验全攻略 - 合扬奢侈品交易中心
  • 2026黔江黄金回收冠军揭晓:永兴荣登榜首!全城免费上门,五大门店实测 - 奢佳美黄金珠宝
  • 如何快速掌握气象数据处理与可视化:MetPy实用指南
  • 抖音GIF动图怎么去水印2026全场景免费工具与实操方法汇总 - 科技热点发布
  • 别再傻傻分不清了!用Excel和Python实战演示标准差、标准误和置信区间的区别
  • 第二个华为长鑫科技,第二算力巨头给员工发200亿
  • 保姆级教程:在Ubuntu 22.04上用virt-manager创建你的第一个KVM虚拟机(附常见错误排查)
  • Redisson 组件 + 支付业务场景落地对照表
  • 【网址带?utm_source=chatgpt.com 的原因】
  • 成都闲置包包回收全攻略:五大实体门店对比、热门款式行情与本地客户案例 - 合扬奢侈品交易中心
  • STM32入门实战:从零开始点亮LED,掌握GPIO与Cube IDE开发全流程
  • 银河麒麟V10/V10.1系统换源保姆级教程(附国内镜像地址及常见错误修复)
  • 从零到一:基于ADS的F类功放谐波匹配实战解析
  • 2026 西安防水维修排行榜|解决卫生间 阳台 地下室 屋顶冻融渗水 - 吉修匠
  • Pearcleaner:你的macOS数字管家,如何彻底告别应用残留?
  • 基于Micro:bit的二进制翻译器:用硬件交互学习ASCII编码原理
  • 15万左右燃油轿车推荐:东风本田英仕派,均衡实力成就B级优选 - 博客万
  • 2026 温州防水维修全攻略|搞定卫生间 阳台 地下室 屋顶台风渗水 - 吉修匠
  • 分支限界法实战:从矩阵规约到堆优化,高效求解TSP
  • 联想拯救者Y7000系列Insyde BIOS隐藏选项一键解锁工具终极指南
  • 从“长相丑”到“美如画”——CSS前世今生与CSS3重磅登场
  • 从软件到硬件:基于树莓派与Arduino的实体AI助手渐进式开发指南
  • 上饶同城黄金回收哪家专业?五家星级门店实测+2026年5月28日实时金价详解,旧金变现更安心 - 润富黄金珠宝行
  • 真实扒皮!小程序商城做的比较好的品牌,老牌黑马全拿捏 - FaiscoJeff
  • 基于LMV358的音频峰值检测电路设计:从原理到实践
  • opc中国的服务对象有哪些
  • 2026年 1,5-戊二醇厂家实力推荐排行榜:高品质溶剂与高端聚酯原料的精准选购指南 - 品牌企业推荐师(官方)
  • Qt6属性绑定避坑指南:从QPropertyData到QBindable,这些细节不注意就踩雷
  • Hourglass:Windows平台极简倒计时工具完全指南