【代码随想录】【算法训练营】【第55天】 [42]接雨水 [84]柱状图中最大的矩形

前言

思路及算法思维,指路 代码随想录。
题目来自 LeetCode。

day 55,又是一个周一,不能再坚持~

题目详情

[42] 接雨水

题目描述

42 接雨水
42 接雨水

解题思路

前提:雨水形成的情况是凹的, 需要前中后3个元素,计算该元素左右两侧的第一个大于该高度的高度
思路:单调递增栈
重点:单调栈的思维

代码实现

C语言
单调递增栈

单调递增栈: 【横向计算形成凹行柱体的雨水】
雨水形成的情况是凹的, 需要当前新的栈顶元素, 计算的是旧的栈顶元素形成的雨水

// 单调递增栈: 雨水形成的情况是凹的, 需要当前新的栈顶元素, 计算的是旧的栈顶元素形成的雨水int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int trap(int* height, int heightSize) {int stack[heightSize];int top = 0;// 遍历计算每个柱子接到的雨水之和int sum = 0;for (int i = 0; i < heightSize; i++) {// 单调递增栈// 当前元素比栈顶元素大,不满足单调递增栈的要求while (top > 0 && height[i] > height[stack[top - 1]]) {//  弹出当前栈顶元素int midIndex = stack[top - 1];top--;// 雨水形成的情况是凹的, 需要当前新的栈顶元素, 计算的是旧的栈顶元素形成的雨水if (top > 0) {int leftIndex = stack[top - 1];sum += (minFun(height[leftIndex], height[i]) - height[midIndex]) * (i - leftIndex - 1);}}stack[top] = i;top++;}return sum;
}
双指针

双指针解法:【竖向计算每个柱体形成的雨水】
两次遍历求当前左侧最高柱子高度maxLeft[i]和右侧最高柱子高度maxRight[i]

// 双指针解法:两次遍历求当前左侧最高柱子高度maxLeft[i]和右侧最高柱子高度maxRight[i]int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int trap(int* height, int heightSize) {int maxLeft[heightSize];int maxRight[heightSize];// 遍历搜索左侧最高柱子高度maxLeft[0] = height[0];for (int i = 1; i < heightSize; i++) {maxLeft[i] = maxFun(height[i], maxLeft[i - 1]);}// 遍历搜索右侧最高柱子高度maxRight[heightSize - 1] = height[heightSize - 1];for (int j = heightSize - 2; j >= 0; j--) {maxRight[j] = maxFun(height[j], maxRight[j + 1]);}// 遍历计算每个柱子接到的雨水之和int sum = 0;for (int k = 0; k < heightSize; k++) {sum += minFun(maxLeft[k], maxRight[k]) - height[k];}return sum;
}

[84] 柱状图中最大的矩形

题目描述

84 柱状图中最大的矩形
84 柱状图中最大的矩形

解题思路

前提:柱状图形成的最大面积,需要求解该柱子左右两侧 最远>=该柱子高度的柱子宽度,即可以求解该柱子左右两侧小于该柱子高度的位置,进而计算所求宽度
思路:单调递减栈
重点:单调栈的思维

代码实现

C语言
单调递减栈
// 单调递减栈: 寻找该柱子左右两侧第一个小于该柱子高度的柱子, 即可找到最后左右两侧最远一个大于该柱子高度的连续柱子, 计算所形成的的最大面积
// 栈顶到栈底,元素依次递减int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int stack[heightsSize];int top = 0;int maxSum = 0;// 遍历for (int i = 0; i < heightsSize; i++) {// 寻找查找栈顶柱子的右侧第一个低于栈顶柱子的柱子位置while (top > 0 && heights[i] < heights[stack[top - 1]]) {// 弹出栈顶元素int midIndex = stack[top - 1];top--;// 计算弹出元素所形成的凸型的面积// 判断是否形成凸的最左侧int leftIndex = 0;if (top > 0) {leftIndex = stack[top - 1] + 1;}int rightIndex = i - 1;int sum = heights[midIndex] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}stack[top] = i;top++;}// 判断是否最后没有形成凸的最右侧,清空栈while (top > 0){int midIndex = stack[top - 1];top--;if (top == 0) {// 此时这个元素为当前元素数组中最小的元素int sum = heights[midIndex] * heightsSize;maxSum = maxFun(maxSum, sum);} else {// 此时单调栈中元素递减int sum = heights[midIndex] * ((heightsSize - 1) - (stack[top - 1] + 1) + 1);maxSum = maxFun(maxSum, sum);}}return maxSum;
}

针对数组单调递增等不能形成凸型的特殊情况, 需要特殊处理,
所以在原数组首尾添加最小元素0, 以便对原数组做同一处理。
优化代码如下。

// 单调递减栈: 寻找该柱子左右两侧第一个小于该柱子高度的柱子, 即可找到最后左右两侧最远一个大于该柱子高度的连续柱子, 计算所形成的的最大面积
// 栈顶到栈底,元素依次递减
// 针对数组单调递增等的特殊情况, 需要特殊处理,所以在原数组首尾添加最小元素0,以便对原数组做同一处理int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int newHeightsSize = heightsSize + 2;int newHeights[newHeightsSize];newHeights[0] = 0;newHeights[newHeightsSize - 1] = 0;for (int t = 1; t < newHeightsSize - 1; t++) {newHeights[t] = heights[t - 1];}int stack[newHeightsSize];int top = 0;int maxSum = 0;// 遍历for (int i = 0; i < newHeightsSize; i++) {// 寻找查找栈顶柱子的右侧第一个低于栈顶柱子的柱子位置// 当遍历到新数组的最后一个元素0, 必可以进入该循环进行处理while (top > 0 && newHeights[i] < newHeights[stack[top - 1]]) {// 弹出栈顶元素int midIndex = stack[top - 1];top--;// 计算弹出元素所形成的凹型的面积// 此处的栈中必有新数组的首元素0int leftIndex = stack[top - 1] + 1;int rightIndex = i - 1;int sum = newHeights[midIndex] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}stack[top] = i;top++;}return maxSum;
}
双指针

寻找该柱子左侧的第一个小于该柱子的高度的下标minLeftIndex[i] 和 右侧第一个小于该柱子的高度的下标minRightIndex[i],
进而计算不小于该柱子高度的连续长度。

// 双指针方法: 寻找该柱子左侧的第一个小于该柱子的高度的下标minLeftIndex[i] 和 右侧第一个小于该柱子的高度的下标minRightIndex[i]
// 计算以当前柱子形成凹形状的柱子的最大面积int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int minLeftIndex[heightsSize];int minRightIndex[heightsSize];// 遍历,寻找该柱子左侧的第一个小于该柱子的高度的下标minLeftIndex[0] = -1;for (int i = 1; i < heightsSize; i++) {int t = i - 1;// 查找左侧第一个小于该柱子高度的柱子下标while (t >= 0 && heights[t] >= heights[i]) {t = minLeftIndex[t];}minLeftIndex[i] = t;}// 遍历,寻找该柱子右侧的第一个小于该柱子的高度的下标minRightIndex[heightsSize - 1] = heightsSize;for (int j = heightsSize - 2; j >= 0; j--) {int t = j + 1;// 查找右侧第一个小于该柱子高度的柱子下标while (t < heightsSize && heights[t] >= heights[j]) {t = minRightIndex[t];}minRightIndex[j] = t;}// 遍历寻找最大面积int sum = 0;int maxSum = 0;for (int k = 0; k < heightsSize; k++) {// 求以当前柱子形成凹形状的柱子的最大面积int leftIndex = minLeftIndex[k] + 1;int rightIndex = minRightIndex[k] - 1;sum = heights[k] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}return maxSum;
}

今日收获

  1. 单调栈,以及为了使用单调栈所做的变化

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

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

相关文章

专业的TPM管理咨询公司有哪些特点?

专业的TPM管理咨询公司&#xff0c;作为现代企业管理和设备维护的重要合作伙伴&#xff0c;其特点不仅体现在技术能力和服务质量上&#xff0c;更在于其独特的经营理念和方法论。以下是专业TPM管理咨询公司所具备的显著特点&#xff1a; 一、全面的技术实力与深厚的行业经验 专…

word 转pdf 中图片不被压缩的方法

word 转pdf 中图片不被压缩的方法 法1&#xff1a; 调节word 选项中的图片格式为不压缩、高保真 法2&#xff1a; 1: word 中的图片尽可能使用高的分辨率&#xff0c;图片存为pnd或者 tif 格式&#xff08;最高清&#xff09; 2: 转化为pdf使用打印机器&#xff0c;参数如下…

分子AI预测赛笔记

#AI夏令营 #Datawhale #夏令营 Taks1 跑通baseline 根据task1跑通baseline 注册账号 直接注册或登录百度账号&#xff0c;etc fork 项目 零基础入门 Ai 数据挖掘竞赛-速通 Baseline - 飞桨AI Studio星河社区 启动项目 选择运行环境&#xff0c;并点击确定&#xff0c;没…

台灯学生用哪个牌子最好?学生用台灯品牌排行榜分析

台灯学生用哪个牌子最好&#xff1f;护眼台灯在近年来成为家长和长时间使用电子设备人群关注的家电/学生产品。对于家中有孩子或经常面对电子屏幕的人士来说&#xff0c;很多人可能已经对这类产品有所了解并进行了购买。然而&#xff0c;部分家长对护眼台灯的认识还不够深入&am…

FFT 简单基础(matlab

使用 fs 进行采样&#xff0c;进行 N点FFT 选择显示0~N/21点的幅值 横坐标对应频率计算公式&#xff1a; fs * n / N 举个梨子&#xff1a; 频率2kHz采样1s&#xff0c;得到2000个点的序列y(n) 对序列y(n)做4096点的FFT 幅值响应对应的横坐标频率…

机器人控制系列教程之Stewart平台简介和运动学分析

Stewart平台简介及应用场景 六自由度 Stewart 并联机器人结构简图如下图所示&#xff0c;主要有一个固定平台和一个移动平台以及六个可伸缩的推杆组成&#xff0c;通常情况下&#xff0c;固定平台与底座连接&#xff0c;移动平台在空间具有六个自由度&#xff0c;通过六个推杆…

价格很实惠,希喂、爱立方、生生不息主食冻干抗得住实测吗?

在挑选主食冻干时&#xff0c;许多宠物主人都会感到头疼。尽管主食冻干相较于普通猫粮具有诸多优势&#xff0c;但其价格也相对高昂。这导致许多宠物主人担心高价购买的主食冻干可能营养价值并不理想。然而&#xff0c;在选择时&#xff0c;我们还需要考虑其他重要因素&#xf…

Spring MVC 中 使用 RESTFul 实现用户管理系统

1. Spring MVC 中 使用 RESTFul 实现用户管理系统 文章目录 1. Spring MVC 中 使用 RESTFul 实现用户管理系统2. 静态页面准备2.1 user.css2.2 user_index.html2.3 user_list.html2.4 user_add.html2.5 user_edit.html 3. SpringMVC环境搭建3.1 创建module&#xff1a;usermgt3…

tapd 与国内外主流的8大项目管理软件大对比

对比Tapd与8大项目管理工具&#xff1a;PingCode、Worktile、Redmine、Teambition、广联达、Jira、禅道、飞书。 Tapd 是腾讯推出的一款敏捷开发管理工具&#xff0c;特别适合那些需要高效协作和快速迭代的敏捷开发团队。它支持多种敏捷方法论&#xff0c;包括Scrum和Kanban&am…

数学建模------Matlab数据可视化

目录 1.plot函数 &#xff08;1&#xff09;函数介绍 &#xff08;2&#xff09;参数介绍 &#xff08;3&#xff09;图形美化 &#xff08;4&#xff09;背景更改 &#xff08;5&#xff09;多组绘制 &#xff08;6&#xff09;图形叠加 &#xff08;7&#xff09;添加…

Elasticsearch备份数据到本地,并导入到新的服务 es 服务中

文章目录 使用elasticsearch-dump工具备份安装node.js(二进制安装)解压设置环境变量安装elasticsearch-dump docker安装使用ES备份文件到本地 使用elasticsearch-dump工具备份 这个工具备份时间比较长 安装node.js(二进制安装) wget https://nodejs.org/dist/v16.18.0/node-…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 英文单词联想(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 https://app5938.acapp.acwing.com.cn/contest/2/problem/OD…

如何利用小程序容器技术搭建小程序生态?

小程序&#xff0c;作为现代移动互联网生态中的重要基础设施&#xff0c;正以其独特的创新性和便捷性展现出勃勃生机。截至2021年&#xff0c;全网小程序的数量已经突破了700万&#xff0c;其中微信小程序的开发者达到了300万之多。这一数字不仅代表了小程序在技术层面的成熟度…

7.4总结

今天写了几道题目 最近&#xff0c;一年级学生马克西姆学习了科拉兹猜想&#xff0c;但他在讲课时没有太注意&#xff0c;所以他认为猜想中提到了以下过程&#xff1a; 有一个变量 $$$x$$$ 和一个常数 $$$y$$$ 。下面的操作要执行 $$$k$$$ 次&#xff1a; - 将 $$$x$$$ 增加…

Studying-代码随想录训练营day29| 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列

第29天&#xff0c;贪心part03&#xff0c;快过半了(ง •_•)ง&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 134.加油站 135. 分发糖果 860.柠檬水找零 406.根据身高重建队列 134.加油站 文档讲解&#xff1a;代码随想录加油站 视频讲解&#xff1a;手撕加油站…

《梦醒蝶飞:释放Excel函数与公式的力量》8.3 COUNTBLANK函数

8.3 COUNTBLANK函数 在数据处理和分析中&#xff0c;我们经常需要识别和统计数据集中的空白单元格。COUNTBLANK函数是Excel中用于统计某个范围内空白单元格数量的强大工具。 8.3.1 函数简介 COUNTBLANK函数用于统计指定范围内的空白单元格数量。这在数据清洗、数据完整性检查…

MySQL之备份与恢复(四)

备份与恢复 存储引擎和一致性 3.复制 从备库中备份最大的好处是可以不干扰主库&#xff0c;避免在主库上增加额外的负载。这是一个建立备库的好理由&#xff0c;即使不需要用它做负载均衡或高可用。如果钱是个问题&#xff0c;也可以把备份用的备库用于其他用户&#xff0c;…

Matlab/simulink三段式电流保护

电流1段仿真波形如下所示 电流2段仿真波形如下所示 电流3段仿真波形如下所示

Centos7安装Minio笔记

一、Minio概述 Minio是一款开源的对象存储服务器&#xff0c;可以运行在多种操作系统上&#xff0c;包括Linux、Windows和MacOS等。提供一种简单、可扩展、高可用的对象存储解决方案&#xff0c;支持多种数据格式&#xff0c;包括对象、块和文件等。Minio是一款强大、灵活、可…

WCCI 2024第三弹:忍者表演惊艳全场,盛大晚宴不容错过

WCCI 2024第三弹&#xff1a;忍者表演惊艳全场&#xff0c;盛大晚宴不容错过&#xff01; 会议之眼 快讯 会议介绍 IEEE WCCI&#xff08;World Congress on Computational Intelligence&#xff09;2024&#xff0c;即2024年IEEE世界计算智能大会&#xff0c;于6月30日至7月…