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

算法题打卡力扣第11题:盛最多水的容器(mid)

题目描述

在这里插入图片描述
在这里插入图片描述
提示:

n == height.length
2 <= n <= 105
0 <= height[i] <= 104

解法一 (暴力解)

首先我的想法是暴力解,依次计算每一个可能的面积大小,然后比较得出最大的面积。

选定一条左边的线 i。

再选定一条右边的线 j。

计算这两条线组成的容器面积:面积 = (j - i) * min(height[i], height[j])。

用两层 for 循环来遍历所有 (i, j) 的组合,不断更新最大面积。
代码如下:

class Solution {
public:int maxArea(vector<int>& height) {int i,j,area=0,max=0;for(i=0;i<height.size();i++){for(j=height.size()-1;j>i;j--){area=(j-i)*min(height[i],height[j]);if(area>max){max=area;}}}return max;}
};

结果:
在这里插入图片描述
显示超出时间限制,让我们来分析一下时间复杂度,两个for循环,1+2+3+n-1=n(1+n-1)/2,所以时间复杂度是O(n^2),空间复杂度是O(1)

解法二 (双指针 from gimini老师)

既然暴力法太慢,我们就要想办法减少不必要的计算。双指针法的精髓就在于每一步都排除掉不可能产生更优解的选项。

1.从哪里开始?
要想让面积最大,面积 = 宽度 × 高度,我们希望宽度和高度都尽可能大。

  • 宽度 最大的情况是什么?当然是选择数组最两端的两条线。
  • 所以,我们可以从这里入手:一个指针 left 指向数组开头,一个指针 right 指向数组末尾。这是我们的初始状态,拥有了最大可能的宽度。
  1. 下一步怎么走?(核心决策)
    现在我们有了一个初始的容器(可能是最大的,也可能不是)。接下来,我们需要移动一个指针,让宽度变窄,来探索有没有可能找到更高的容器,从而获得更大的总面积。

关键问题: 我们应该移动 left 指针还是 right 指针?

让我们来分析一下:

  • 当前容器的面积是 (right - left) * min(height[left], height[right])。
  • 容器的储水量由较短的那块木板决定(木桶效应)。

假设 height[left] 比 height[right] 短。

  • 如果我们移动右指针 right 向左,新的宽度肯定变小了,而容器的新高度仍然受限于 height[left] (因为新的右板即使再高,短板还是 height[left])。所以,面积必然会变小。移动长板对于当前情况来说,没有任何益处。
  • 反之,如果我们移动左指针 left 向右,虽然宽度也变小了,但我们给了自己一个寻找更高左板的机会。如果新的 height[left] 变得更高,就有可能弥补宽度减小的损失,从而得到一个更大的面积。

结论:

在每一步,我们都应该移动指向较短木板的那个指针。这是整个算法最核心的贪心思想。

算法流程总结

  • 初始化:

左指针 left = 0。

右指针 right = height.length - 1。

最大面积 maxArea = 0。

  • 循环:只要 left < right,就不断重复以下步骤:

计算当前宽度 width = right - left。

找出较短的板高 h = min(height[left], height[right])。

计算当前面积 currentArea = width * h。

更新历史最大面积 maxArea = max(maxArea, currentArea)。

移动指针:

如果 height[left] < height[right],则 left++。

否则,right–。

  • 结束:当 left 和 right 相遇,说明所有可能性都已探索完毕,返回 maxArea。

完整代码如下:

class Solution {
public:int maxArea(vector<int>& height) {int left=0,right = height.size() - 1,maxArea = 0;int width=0,currentArea=0,h=0;while(left < right){width = right - left;h = std::min(height[left],height[right]);currentArea = width * h;maxArea = std::max(maxArea,currentArea);if(height[left]<height[right]){left++;}else{right--;}}return maxArea;}
};

运行结果如下:
在这里插入图片描述
时间复杂度分析:
只使用了一个for循环,时间复杂度为O(n)
空间复杂度为O(1)
ok,双指针太好用了!!!
如果还有不懂的小伙伴可以看看这个视频讲的不错~
盛最多水的容器 接雨水
ok,see you next time!

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

相关文章:

  • TF-IDF实战——《红楼梦》文本分析
  • 深度学习(5):激活函数
  • 敏感数据目录是什么?如何快速构建企业自身的敏感数据目录
  • flex-wrap子元素是否换行
  • Linux:磁盘管理
  • 使用HtmlAgilityPack+PuppeteerSharp+iText7抓取Selenium帮助文档
  • 学习嵌入式的第十九天——Linux——文件编程
  • 【MyBatis批量更新实现】按照list传入批量更新
  • java中数组和list的区别是什么?
  • 如何生成.patch?
  • 旧版MinIO的安装(windows)、Spring Boot 后端集成 MinIO 实现文件存储(超详细,带图文)
  • Spring Boot 3 连接池最大连接数设置建议
  • HTTP 协议详细介绍
  • Spring事务管理实战:从注解到进阶
  • SQL 查询慢?先从 EXPLAIN 看起
  • 可视化调试LangChain SQLChatMessageHistory:SQLite数据库查看全攻略
  • 智算赋能:移动云助力“世界一流数据强港”建设之路
  • 什么是内外网文件传输?如何确保文件在内外网间安全、高效地传输呢?
  • 层次视觉 Transformer 与分布级特征精炼:面向多模态疾病诊断与机器遗忘的深度学习框架研究
  • [idekCTF 2025] diamond ticket
  • C#自定义日期时间选择器
  • 2025 电赛 C 题完整通关攻略:从单目标定到 2 cm 测距精度的全流程实战
  • C++编程学习(第22天)
  • k8s资源管理
  • 集成电路学习:什么是CV计算机视觉
  • 加密界的“瑞士军刀“-----VeraCrypt 加密原理与实操
  • 【数据结构】——栈(Stack)的原理与实现
  • iscc2025决赛wp
  • Redis面试精讲 Day 20:Redis大规模部署性能调优
  • MCP协议更新:从HTTP+SSE到Streamable HTTP,大模型通信的进化之路