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

代码随想录算法训练营第四十九天|单调栈part2

42. 接雨水

题目链接:42. 接雨水 - 力扣(LeetCode)

文章讲解:代码随想录

思路:

height = [4,2,0,3,2,5]为例

先求每根柱子左右边第一个高的

得到

5 3 3 5 5 -1

-1 4 2 4 3 -1

左右两边都不为-1才能接住水

初始化ans 为0

左右两边都不为-1的置为1

对于1 里边都能盛水

所盛水是 1的左右两边柱子的最小值 然后再减去1的柱子里边原本的高度

然后统计所有的水 j

class Solution {
public:int trap(vector<int>& height) {vector<int>right(height.size(),-1);vector<int>left(height.size(),-1);stack<int>st;st.push(0);for(int i=1;i<height.size();i++){   //右边第一个大的while(!st.empty()&&height[i]>height[st.top()]){right[st.top()]=height[i];st.pop();}st.push(i);}stack<int>lst;lst.push(height.size()-1);for(int i=height.size()-2;i>=0;i--){   //左边第一个大while(!lst.empty()&&height[i]>height[lst.top()]){left[lst.top()]=height[i];lst.pop();}lst.push(i);}vector<int>ans(height.size(),1);for(int i=0;i<height.size();i++){  //能盛水的单位if(left[i]==-1||right[i]==-1){ans[i]=0;}}for(int i=0;i<height.size();i++){if(ans[i]){int l=i-1;              //能盛水的区间int r;for(int j=i;j<height.size();j++){if(ans[j]==0){r=j;break;}}int num=min(height[l],height[r]);for(int j=l+1;j<r;j++){    //能盛水的区间每个柱子能接的水ans[j]=num-height[j];}i=r-1;}}int result=0;for(auto &x:ans){result+=x;}return result; }
};

解法2:

暴力解:

需要优化

class Solution {
public:int trap(vector<int>& height) {//暴力解法 求每根柱子能盛的水vector<int>lmax(height.size(),0);vector<int>rmax(height.size(),0);vector<int>ans(height.size(),0);int n=height.size();// 计算每个柱子左边最高的柱子for (int i = 1; i < n; ++i) {lmax[i] = max(lmax[i - 1], height[i - 1]);}// 计算每个柱子右边最高的柱子for (int i = n - 2; i >= 0; --i) {rmax[i] = max(rmax[i + 1], height[i + 1]);}for(int i=1;i<height.size()-1;i++){ans[i]=min(lmax[i],rmax[i])-height[i];}int result=0;for(auto &x:ans){if(x>=0) result+=x;}return result; }
};

 方法三:

单调栈

class Solution {
public:int trap(vector<int>& height) {int result=0;stack<int>st;st.push(0);for(int i=1;i<height.size();i++){if(!st.empty()&&height[i]<height[st.top()]){st.push(i);}else if(!st.empty()&&height[i]==height[st.top()]){st.push(i);}else{while(!st.empty()&&height[i]>height[st.top()]){int mid=st.top();st.pop();if (st.empty()) break;  // ✅ 必须加这个判断int h=min(height[st.top()],height[i]);int w=i-st.top()-1;//水量计算result+=w*(h-height[mid]);    }st.push(i);   //这一句放在循环外}}return result; }
};
84.柱状图中最大的矩形
题目链接:84. 柱状图中最大的矩形 - 力扣(LeetCode)
文章讲解:代码随想录

 思路:

考虑每个柱子的高度为高,然后计算最大的宽度,再计算面积。

比较上述面积的最大值

宽度的计算在于 寻找当前柱子左右两边第一个比它小的 l和r

那么w=r-l-1

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int size=heights.size();vector<int>leftMin(heights.size(),-1);   //左边第一个小的vector<int>rightMin(heights.size(),size); //右边第一个小的stack<int>lst;stack<int>rst;rst.push(0);for(int i=1;i<size;i++){while(!rst.empty()&&heights[i]<heights[rst.top()]){rightMin[rst.top()]=i;rst.pop();}rst.push(i);}lst.push(size-1);for(int i=size-2;i>=0;i--){while(!lst.empty()&&heights[i]<heights[lst.top()]){leftMin[lst.top()]=i;lst.pop();}lst.push(i);}int result=0;for(int i=0;i<size;i++){int r=rightMin[i];int l=leftMin[i];int w=r-l-1;int area=w*heights[i];result=max(result,area);}return result;}
};

http://www.xdnf.cn/news/1119619.html

相关文章:

  • PHP password_verify() 函数
  • vue vxe-tree 树组件加载大量节点数据,虚拟滚动的用法
  • 【AutoCAD全网最新版】AutoCAD 2026 保姆级下载安装注册使用详细图文教程
  • 借助DeepSeek编写输出漂亮表格的chdb客户端
  • [源力觉醒 创作者计划]_文心大模型4.5开源部署指南:从技术架构到实战落地
  • sfe_py的应力云图计算与显示step by step
  • 【LeetCode240.搜索二维矩阵Ⅱ】以及变式
  • iOS高级开发工程师面试——RunLoop
  • C++类模版与友元
  • 大数据领域开山鼻祖组件Hadoop核心架构设计
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GithubProfies(GitHub 个人资料)
  • 编译器 VS 解释器
  • 电脑升级Experience
  • Linux操作系统之信号:信号的产生
  • 【C++进阶】---- 多态
  • 鹧鸪云:别墅光储项目方案设计的最终选择
  • 【Linux系统】进程切换 | 进程调度——O(1)调度队列
  • Linux:3_基础开发⼯具
  • 【Linux】基本指令详解(一) 树状文件结构、家目录、绝对/相对路径、linux文件类型
  • 使用systemctl命令控制软件的启动和关闭
  • 打破空间边界!Nas-Cab用模块化设计重构个人存储逻辑
  • 各种开发语言主要语法对比
  • Codeforces Round 1019 (Div. 2) A-D
  • GPU网络运维
  • UV vs Pip:Python 包管理的革命性进化
  • 【安卓笔记】进程和线程的基础知识
  • 实现高效、可靠的基于骨骼的人体姿态建模(第二章 基于三维人体姿态回归的语义图卷积网络)
  • 马蹄集 BD202401补给
  • Elasticsearch 9.x 升级变化
  • Swift 解 LeetCode 326:两种方法判断是否是 3 的幂,含循环与数学技巧