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

【Leetcode】11. 盛最多水的容器

文章目录

  • 题目
  • 思路
    • 数学证明
      • 证明1: 局部正确性(为什么移动短板?)
      • 证明2: 全局完整性(不会错过最优解)
  • 代码
    • C++
    • Java
    • Python
  • 复杂度分析
    • 时间复杂度
    • 空间复杂度
  • 总结

题目

给你一个长度为n的整数数组height,其中height[i]表示坐标(i, height[i])处的一条垂直线(柱子)。你需要选择两条垂直线,与x轴共同构成一个容器,求出这个容器能盛的最多水量(面积)。

注意

  • 容器不能倾斜。
  • 水量 = min(height[i], height[j]) * (j - i),其中i < j
  • 返回最大水量。

示例

  • 输入:height = [1,8,6,2,5,4,8,3,7]
  • 输出:49
  • 解释:选择索引1(高度8)和索引8(高度7),min(8,7)=7,宽度=7,面积=49。

约束

  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

题目链接🔗

思路

这个问题可以使用双指针法高效求解,时间复杂度为O(n)。核心思想是从数组两端开始,使用两个指针向中间移动,总是移动高度较小的指针(短板),因为它限制了当前面积。通过贪心策略,逐步逼近最大面积。

  • 初始化左指针l = 0,右指针r = n-1,最大面积ans = 0
  • while (l < r):
    • 计算当前面积:area = min(height[l], height[r]) * (r - l)
    • 更新ans = max(ans, area)
    • 如果height[l] <= height[r],则l++;否则r--
  • 返回ans

这种方法从最大宽度开始,移动短板以追求更高的高度,从而有机会增大面积。下面我们通过数学证明来验证其正确性。

数学证明

双指针法的正确性基于贪心和反证法。我们证明:(1) 局部移动正确;(2) 全局不会错过最优解。

证明1: 局部正确性(为什么移动短板?)

假设当前lr,且height[l] <= height[r](对称情况类似)。

  • 当前面积A = height[l] * (r - l)

  • 如果移动长板(r--r'):

    • 新高度min' = min(height[l], height[r']) <= height[l]
    • 新宽度(r' - l) = (r - l) - 1 < 原宽度
    • 新面积A' <= height[l] * ((r - l) - 1) < A(严格小于)。
    • 结论:无益,不会产生更大面积。
  • 如果移动短板(l++l'):

    • 新高度min' = min(height[l'], height[r]),可能> height[l]
    • 新面积可能> A

通过归纳:初始步正确,每步移动短板保持性质,整个算法局部正确。

证明2: 全局完整性(不会错过最优解)

假设存在最优对(i, j),面积A_max = min(height[i], height[j]) * (j - i) 是全局最大。我们证明算法必在某步计算它。

  • 反证假设:算法从未计算(i, j)

  • 算法性质:l从0单增,r从n-1单减;初始l <= i < j <= r。

  • 关键:算法只“跳过”不可能是最优的柱子对。

    • (i, j)为最优,假设height[i] <= height[j]
    • 当l第一次到达i时,r必然还在 >= j(因为r只在height[r]是短板时减小,且height[j] >= height[i]`)。
    • 然后,继续移动,直到r = j,此时计算(i, j)
  • 归纳证明

    • 基例:n=2,初始计算。
    • 假设对<n成立。对n,第一步计算(0, n-1)。如果它是最大,完成;否则移动短板,子数组由假设覆盖。

结论:所有可能的最优对都会被访问,算法正确。

代码

C++

int maxArea(int* height, int heightSize) {int l = 0, r = heightSize - 1;int ans = 0;int min = 0, area = 0;while (l < r) {if (height[l] < height[r]) min = height[l];else min = height[r];area = min * (r - l);if (ans < area) ans = area;if (height[l] <= height[r]) {++l;} else {--r;}}return ans;
}

Java

class Solution {public int maxArea(int[] height) {int l = 0;int r = height.length - 1;int ans = 0;while (l < r) {int minHeight = Math.min(height[l], height[r]);int area = minHeight * (r - l);ans = Math.max(ans, area);if (height[l] <= height[r]) {l++;} else {r--;}}return ans;}
}

Python

class Solution:def maxArea(self, height: List[int]) -> int:l, r = 0, len(height) - 1ans = 0while l < r:min_height = min(height[l], height[r])area = min_height * (r - l)ans = max(ans, area)if height[l] <= height[r]:l += 1else:r -= 1return ans

复杂度分析

时间复杂度

O(n),其中n是height数组的长度。每个指针最多移动n次,整个数组被遍历一次。

空间复杂度

O(1),只使用了常量额外空间,不依赖输入大小。

总结

双指针法巧妙地解决了这个问题,通过贪心移动短板,避免了暴力枚举的低效。数学证明确保了算法的正确性,加深了对贪心算法的理解。

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

相关文章:

  • 房地产开发建设网站温州网站建
  • 上海单位建设报建网站内蒙古城乡建设部网站首页
  • 网站关键词词库怎么做p2p提供网站建设违法
  • wordpress 文档制作主题中山seo技术
  • 智慧物流赛项的技术平台与环境建设:打造虚实融合的竞技舞台
  • 中卫市住房建设局网站山西长治做网站公司有哪些
  • Python 日历记事本完整开发教程(自绘日历版)
  • 【ROS2学习笔记】DDS(数据分发服务)
  • 网站开发公司徐州三明seo培训
  • 做品牌 需要做网站吗网站建设运营期末考试
  • id注册网站wordpress访问不了
  • 阿克苏网站建设咨询logo图案大全
  • 百度网站建设电话网站seo优化技巧
  • 龙华品牌网站建设石景山区公司网站建设
  • 河南省建设网站电力建设期刊网站投稿
  • 北京做网站公司排名浩森宇特江苏省建设档案网站
  • 给网站添加百度地图本地电脑做服务器 建网站
  • wordpress govpress 汉化北京网站推广优化公司
  • 网站安全防护方案北京微信网站建设电话咨询
  • 优秀网站架构网站seo什么意思
  • 个人可以做电视台网站吗怎么做网络营销
  • Python 题目练习 Day1.2
  • 做宣传网站需要多少钱中山移动网站建设报价
  • 网站开发开题报告怎么写北京室内设计公司排名
  • 向量数据库 Milvus 的高可用
  • 轻量级、高性能的RPC框架——Dubbo
  • 预约网站模板出境旅游哪个网站做的好
  • 那些网站可以做海报网站品牌建设方案
  • 旺道网站排名优化房产信息网显示限售
  • 网站反向绑定域名优秀的电商app设计网站