代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形

接雨水

42. 接雨水 - 力扣(LeetCode)

暴力解法

对计算接到的雨水,有两种方式,一是按照行来计算。

另一种是按列计算

按列计算容易不乱。基本思路如下:

对每列i进行循环,在循环中,找到该列左侧的最大高度leftHeight和该列右侧的最大高度rightHeight,该列能接到的雨水为两者较小值减去该列的高度。

h = min(leftHeight,rightHeight) - height[i] 

当h大于0时,将结果累加进最后的返回结果result中.

具体思路可以看代码随想录 (programmercarl.com)

代码如下

class Solution {
public://计算给定高度数组中能接的雨水量int trap(vector<int>& height) {int sum = 0; // sum 用于累计接到的雨水量for(int i = 0; i < height.size(); i++){ // 遍历数组中的每个元素if(i == 0 || i == height.size() - 1) // 数组的第一个和最后一个元素不能接雨水continue; // 跳过这两个元素int rightHeight = height[i]; // 右边最高的柱子高度,初始设为当前柱子高度int leftHeight = height[i]; // 左边最高的柱子高度,初始设为当前柱子高度for(int r = i + 1; r < height.size(); r++){ // 向右扫描,找到右边最高的柱子if(height[r] > rightHeight)rightHeight = height[r];}for(int l = i - 1; l >= 0; l--){ // 向左扫描,找到左边最高的柱子if(height[l] > leftHeight)leftHeight = height[l];}int h = min(leftHeight, rightHeight) - height[i]; // 计算当前位置可以接的雨水量if(h > 0)sum += h; // 如果可以接雨水,则加到总雨水量上}return sum; // 返回总的接雨水量}
};

算法的时间复杂度为O(n^2),对于每个元素都要向左右遍历一次获取最大的leftheight和rightheight,最后2个案例会超时,ac不了,空间复杂度为O(1)。

双指针法

在上述的暴力解法中,如果我们进行调试的话,会发现每次的运行都会左右遍历一次以获取最大的leftheight和rightheight,而这有很多的计算浪费,所以我们可以在开始就从左到右,从右到左遍历一次数组,得到两个数组,分别表示每列i的leftheight和rightheight,然后用上述计算h的方法再计算一次,将算法的时间复杂度降为O(n)。

class Solution {
public:int trap(vector<int>& height) {int sum = 0;vector<int> leftHeight(height.size(), 0); // 创建一个数组来存储每个位置的左边最高柱子高度vector<int> rightHeight(height.size(), 0); // 创建一个数组来存储每个位置的右边最高柱子高度int maxHeight_left_temp = height[0]; // 初始化左边最高柱子高度为第一个元素的高度int maxHeight_right_temp = height[height.size() - 1]; // 初始化右边最高柱子高度为最后一个元素的高度for (int i = 1; i < height.size(); i++) {maxHeight_left_temp = max(maxHeight_left_temp, height[i]); // 更新左边最高柱子高度leftHeight[i] = maxHeight_left_temp; // 存储左边最高柱子高度}for (int i = height.size() - 2; i >= 0; i--) {maxHeight_right_temp = max(maxHeight_right_temp, height[i]); // 更新右边最高柱子高度rightHeight[i] = maxHeight_right_temp; // 存储右边最高柱子高度}// 再次遍历数组,计算每个位置可以接的雨水量for (int i = 0; i < height.size(); i++) {int h = min(leftHeight[i], rightHeight[i]) - height[i]; // 计算当前位置可以接的雨水量if (h > 0)sum += h; // 如果可以接雨水,则加到总雨水量上}return sum;}
};

算法的时间复杂度为O(n),空间复杂度为O(n)(2个长度为n的数组),以空间换时间。

单调栈法

这里想像这样一个问题,接雨水即需要找到当前柱子右侧的大于等于该柱子高度的柱子,然后计算接到的雨水,因此,可以使用单调栈法。

从左到右遍历时,需要找到比当前元素大的元素,考虑使用单调递增栈(什么问题使用什么栈参考之前day52的文章)

class Solution {
public:int trap(vector<int>& height) {stack<int> st; // 创建一个栈来存储柱子的索引int sum = 0; // sum 用于累计接到的雨水量st.push(0); // 先将第一个柱子的索引入栈for (int i = 1; i < height.size(); i++) { // 从第二个柱子开始遍历数组if (height[i] < height[st.top()]) { // 如果当前柱子高度小于栈顶柱子高度st.push(i); // 将当前柱子的索引入栈} else if (height[i] == height[st.top()]) { // 如果当前柱子高度等于栈顶柱子高度st.pop(); // 弹出栈顶元素st.push(i); // 将当前柱子的索引入栈} else { // 如果当前柱子高度大于栈顶柱子高度while (!st.empty() && height[i] > height[st.top()]) { // 当栈不为空且当前柱子高度大于栈顶柱子高度时int mid = st.top(); // 获取栈顶柱子的索引st.pop(); // 弹出栈顶元素if (!st.empty()) { // 如果栈不为空int h = min(height[st.top()], height[i]) - height[mid]; // 计算凹槽的高度int w = i - st.top() - 1; // 计算凹槽的宽度sum += h * w; // 计算凹槽可以接的雨水量,并加到总雨水量上}}}st.push(i); // 将当前柱子的索引入栈}return sum; // 返回总的接雨水量}
};

算法的时间复杂度为O(n),空间复杂度为O(n)。

柱状图中最大的矩形

84. 柱状图中最大的矩形 - 力扣(LeetCode)

暴力解法

类似上题的想法,对每个列i找到左方第一个高度小于它的列left和右方第一个高度小于它的列right,面积为(right - left - 1) *  heights[i]。同样,算法的时间复杂度为O(n^2),空间复杂度为O(1)。

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int sum = 0; // sum 用于存储最大矩形面积for (int i = 0; i < heights.size(); i++) { // 遍历数组中的每个元素int left = i; // 初始化左边边界为当前柱子int right = i; // 初始化右边边界为当前柱子// 向左扫描,找到左边第一个高度小于当前柱子的位置for (left = i; left >= 0; left--) {if (heights[left] < heights[i]) break;}// 向右扫描,找到右边第一个高度小于当前柱子的位置for (right = i; right < heights.size(); right++) {if (heights[right] < heights[i]) break;}// 计算以当前柱子为高的矩形面积int w = right - left - 1; // 矩形的宽度int h = heights[i]; // 矩形的高,即当前柱子的高度sum = max(sum, w * h); // 更新最大矩形面积}return sum; // 返回最大矩形面积}
};

超时。

双指针法

有些难度,参考代码随想录代码随想录 (programmercarl.com)

class Solution {
public:int largestRectangleArea(vector<int>& heights) {vector<int> minLeftIndex(heights.size());vector<int> minRightIndex(heights.size());int size = heights.size();// 记录每个柱子 左边第一个小于该柱子的下标minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环for (int i = 1; i < size; i++) {int t = i - 1;// 这里不是用if,而是不断向左寻找的过程while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];minLeftIndex[i] = t;}// 记录每个柱子 右边第一个小于该柱子的下标minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环for (int i = size - 2; i >= 0; i--) {int t = i + 1;// 这里不是用if,而是不断向右寻找的过程while (t < size && heights[t] >= heights[i]) t = minRightIndex[t];minRightIndex[i] = t;}// 求和int result = 0;for (int i = 0; i < size; i++) {int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);result = max(sum, result);}return result;}
};

算法的时间复杂度为O(n),空间复杂度也为O(n)。

单调栈法

代码随想录 (programmercarl.com)

明天补

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/38816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS Next开发学习手册——视频播放 (Video)

Video组件用于播放视频文件并控制其播放状态&#xff0c;常用于为短视频和应用内部视频的列表页面。当视频完整出现时会自动播放&#xff0c;用户点击视频区域则会暂停播放&#xff0c;同时显示播放进度条&#xff0c;通过拖动播放进度条指定视频播放到具体位置。具体用法请参考…

寒武纪实现高维向量的softmax进阶优化和库函数对比

关于寒武纪编程可以参考本人之前的文章添加链接描述,添加链接描述,添加链接描述 实验证明,axis=0和axis=-1的时候,手写softmax速度可以和库函数媲美,甚至于更甚一筹。 src/softmax.mlu #include <bang.h> #include

Nik Collection by DxO:摄影师的创意利器与调色宝典

在数码摄影的世界里&#xff0c;后期处理是摄影师们展现创意、调整细节、提升作品质量的重要步骤。而Nik Collection by DxO作为一款由DxO公司开发的强大照片编辑插件套件&#xff0c;为摄影师们提供了一套全面的、功能丰富的工具集&#xff0c;让他们的创意得以充分发挥。 Ni…

遇到多语言跨境电商系统源码问题?这里有解决方案!

从手机到电脑&#xff0c;从线下到线上&#xff0c;如今&#xff0c;跨境电商正在打破地域界限&#xff0c;成为全球贸易的新引擎。在这个全球化的背景下&#xff0c;跨境电商平台的运营也面临着一系列的挑战&#xff0c;其中之一就是多语言问题。如果你遇到了多语言跨境电商系…

2065. 最大化一张图中的路径价值 Hard

给你一张 无向 图&#xff0c;图中有 n 个节点&#xff0c;节点编号从 0 到 n - 1 &#xff08;都包括&#xff09;。同时给你一个下标从 0 开始的整数数组 values &#xff0c;其中 values[i] 是第 i 个节点的 价值 。同时给你一个下标从 0 开始的二维整数数组 edges &#xf…

7基于SpringBoot的SSMP整合案例-表现层开发

目录 1.基于Restfu1进行表现层接口开发 1.1创建功能类 1.2基于Restful制作表现层接口 2.接收参数 2使用Apifox测试表现层接口功能 保存接口&#xff1a; 分页接口&#xff1a; 3.表现层一致性处理 3.1先创建一个工具类&#xff0c;用作后端返回格式统一类&#xff1a;…

springboot校园购物网站APP-计算机毕业设计源码041037

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

笔记-Python文件: .py、.ipynb、.pyi、.pyc、​.pyd

.py 最常见的Python代码文件后缀名&#xff0c;官方称Python源代码文件。 不用过多解释了~ .ipynb 这个还是比较常见的&#xff0c;.ipynb是Jupyter Notebook文件的扩展名&#xff0c;它代表"IPython Notebook"。 学过数据分析&#xff0c;机器学习&#xff0c;深度…

算法笔记:模拟过程(螺旋遍历矩阵)

1 模拟过程 “模拟过程题”通常指的是那些要求编程者通过编写代码来“模拟”或重现某个过程、系统或规则的题目。这类题目往往不涉及复杂的数据结构或高级算法&#xff0c;而是侧重于对给定规则的精确执行和逻辑的清晰表达。 其中螺旋遍历矩阵的题目就是一类典型的模拟过程题…

明日周刊-第14期

不好意思又拖更了哈哈哈。不过赶在7月的第一天&#xff0c;打算更新一下。建党节&#xff0c;值得纪念的一天。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 国内科技新闻 深中通道建成通车 时间&#xff1a;2024年6月30日 内容&#xff1a;深圳至中山跨江通道正式建成开…

助你疯狂涨点!16种注意力机制魔改模型!

【注意力机制模型】是近年来在深度学习领域中备受关注的一项技术。它通过为输入数据中的重要部分分配更高的权重&#xff0c;从而增强模型对关键特征的识别能力。注意力机制在神经网络的不同层次上应用&#xff0c;可以动态调整注意力权重&#xff0c;从而提高模型的性能。该技…

快团团团长如何导出自提点订单?免费教程一学就会

快团团团长如何导出自提点订单&#xff1f; 一、xcx端如何导出自提点订单&#xff1f; 进入团购页面&#xff0c;在订单管理——订单导出中&#xff0c;可导出自提点商品汇总单和自提点订单 注意&#xff1a;只有自提团才能导出自提点商品汇总表 二、电脑端如何导出自提点订…

汇聚荣拼多多电商好不好?

拼多多电商好不好?这是一个值得探讨的问题。拼多多作为中国领先的电商平台之一&#xff0c;以其独特的商业模式和创新的营销策略吸引了大量用户。然而&#xff0c;对于这个问题的回答并不是简单的好或不好&#xff0c;而是需要从多个方面进行综合分析。 一、商品质量 来看拼多…

YOLOv8改进 | 主干网络 | C2f融合动态卷积模块ODConv

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40篇内容&#xff0c;内含各种Head检测头、损失函数Loss、…

C#中的时间数据格式化详解与应用示例

文章目录 1、基本概念基本格式化方法 2、实用的时间格式化方法格式化日期格式化时间格式化时间戳解析日期时间字符串 3、实际应用4、应用示例结论 在软件开发中&#xff0c;时间数据是无处不在的。无论是用户登录时间、数据备份时间&#xff0c;还是日志记录&#xff0c;都需要…

复兴社开展金融知识普及活动

复兴社自成立以来&#xff0c;始终致力于推动全国经济发展、实现共同富裕。金融知识的普及是实现这一目标的重要环节。为此&#xff0c;复兴社在全国范围内开展了一系列金融知识普及活动&#xff0c;旨在提升贫困地区人民的金融素养&#xff0c;助力他们实现经济自立和发展。 复…

【Emacs Verilog mode保姆级的使用指南】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

vision mamba-yolov8:结合Vmamba的yolov8目标检测改进实现

1.vision mamba结构与原理 Mamba成功的关键在于S6模型&#xff0c;该模型为NLP任务设计&#xff0c;通过选择性扫描空间状态序列模型&#xff0c;将二次复杂度降低至线性。但由于视觉信号&#xff08;如图像&#xff09;的无序性&#xff0c;Mamba的S6模型不能直接应用&#xf…

SQLAlchemy(alembic)和Flask-SQLAlchemy入门教程

SQLAlchemy 是 Python 生态中最流行的 ORM 类库&#xff0c;alembic 用来做 OMR 模型与数据库的迁移与映射&#xff0c;Flask-SQLAlchemy 是 Flask 的扩展&#xff0c;可为应用程序添加对 SQLAlchemy 的支持&#xff0c;简化 SQLAlchemy 与 Flask 的使用。 一.SQLAlchemy 和 a…

GraphPad Prism生物医学数据分析软件下载安装 GraphPad Prism轻松绘制各种图表

Prism软件作为一款功能强大的生物医学数据分析与可视化工具&#xff0c;其绘图功能尤为突出。该软件不仅支持绘制基础的图表类型&#xff0c;如直观明了的柱状图、展示数据分布的散点图&#xff0c;以及描绘变化趋势的曲线图&#xff0c;更能应对复杂的数据呈现需求&#xff0c…