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

news/2024/11/15 11:50:31/文章来源:https://www.cnblogs.com/frontpen/p/18367606

42. 接雨水

题目链接:https://leetcode.cn/problems/trapping-rain-water/
文章讲解:https://programmercarl.com/0042.接雨水.html
题目难度:困难
视频讲解:https://www.bilibili.com/video/BV1uD4y1u75P/
题目状态:这道题目在LeetCode Top100中做过,使用两种方法,再回顾一下

思路一:单调栈

  1. 栈的作用

    • 栈用于存储柱子的索引,确保栈中的高度是递减的。
  2. 遍历数组

    • 对于每个柱子,如果当前柱子高度大于栈顶柱子高度,说明可以形成一个凹槽来积水。
  3. 计算积水

    • 弹出栈顶元素,作为凹槽的底部。
    • 如果栈为空,说明没有左边界,无法积水。
    • 否则,计算左边界(新的栈顶)与当前柱子之间的宽度。
    • 计算高度差:min(height[left], height[i]) - height[top]
    • 计算当前积水量并累加到结果中。
  4. 继续遍历

    • 将当前柱子的索引压入栈中,继续处理下一个柱子。

代码一:

class Solution {
public:int trap(vector<int>& height) {int ans = 0;stack<int> stk;int n = height.size();for(int i = 0; i < n; ++i) {while(!stk.empty() && height[i] > height[stk.top()]) {int top = stk.top();stk.pop();if(stk.empty()) break;int left = stk.top();int currWidth = i - left - 1;int currHeight = min(height[left], height[i]) - height[top];ans += currWidth * currHeight;}stk.push(i);}return ans;}
};

消耗一:

image

思路二:动态规划

  1. 初始化

    • 检查输入数组是否为空。如果是,直接返回0。
  2. 计算左边最大高度

    • 创建一个数组 leftMax,其中 leftMax[i] 存储从位置0到位置i的最大高度。
    • 通过遍历数组,逐步更新 leftMax
  3. 计算右边最大高度

    • 创建一个数组 rightMax,其中 rightMax[i] 存储从位置i到数组末尾的最大高度。
    • 通过反向遍历数组,逐步更新 rightMax
  4. 计算总积水量

    • 遍历每个位置,计算当前位置能存储的水量:min(leftMax[i], rightMax[i]) - height[i]
    • 将每个位置的水量累加到总水量中。
  5. 返回结果

    • 返回总积水量。

代码二:

class Solution {
public:int trap(vector<int>& height) {int n = height.size();if(n == 0) return 0;vector<int> leftMax(n);leftMax[0] = height[0];for(int i = 1; i < n; ++i) {leftMax[i] = max(leftMax[i - 1], height[i]);}vector<int> rightMax(n);rightMax[n - 1] = height[n - 1];for(int i = n - 2; i >= 0; --i) {rightMax[i] = max(rightMax[i + 1], height[i]);}int ans = 0;for(int i = 0; i < n; ++i) {ans += min(leftMax[i], rightMax[i]) - height[i];}return ans;}
};

消耗二:

image

84. 柱状图中最大的矩形

题目链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/
文章讲解:https://programmercarl.com/0084.柱状图中最大的矩形.html
题目难度:困难
视频讲解:https://www.bilibili.com/video/BV1Ns4y1o7uB/
题目状态:不会做,看题解

思路一:双指针

  1. 初始化:

    • minLeftIndex[0] 初始化为 -1,表示最左边界。
    • minRightIndex[size - 1] 初始化为 size,表示最右边界。
  2. 计算 minLeftIndex:

    • 从左到右遍历柱子,对于每个柱子 i,向左寻找第一个高度小于 heights[i] 的柱子。
    • 使用变量 ti-1 开始向左查找,更新 minLeftIndex[i] 为找到的下标。
    • 如果当前柱子 t 的高度大于等于 heights[i],继续向左查找 minLeftIndex[t]
  3. 计算 minRightIndex:

    • 从右到左遍历柱子,对于每个柱子 i,向右寻找第一个高度小于 heights[i] 的柱子。
    • 使用变量 ti+1 开始向右查找,更新 minRightIndex[i] 为找到的下标。
    • 如果当前柱子 t 的高度大于等于 heights[i],继续向右查找 minRightIndex[t]
  4. 计算最大矩形面积:

    • 遍历每个柱子 i,计算以该柱子为高的最大矩形面积:heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1)
    • 更新 result 为所有计算出的矩形面积的最大值。
  5. 返回结果:

    • 返回 result,即最大矩形的面积。

代码一:

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int len = heights.size();vector<int> minLeftIndex(len);vector<int> minRightIndex(len);minLeftIndex[0] = -1;for(int i = 1; i < len; ++i) {int t = i - 1;while(t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];minLeftIndex[i] = t;}minRightIndex[len - 1] = len;for(int i = len - 2; i >= 0; --i) {int t = i + 1;while(t < len && heights[t] >= heights[i]) t = minRightIndex[t];minRightIndex[i] = t;}int ans = 0;for(int i = 0; i < len; ++i) {int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);ans = max(sum, ans);}return ans;}
};

消耗一:

image

思路二:单调栈

  1. 初始化栈:

    • 插入 0 后,栈中初始含有下标 0
  2. 遍历柱子:

    • 从下标 1 开始遍历 heights 数组。
  3. 处理情况:

    • heights[i] < heights[st.top()] 时,表示可以计算以栈顶柱子为高的矩形面积。
    • 不断弹出栈顶元素,直到栈为空或栈顶柱子高度不大于当前柱子高度。
    • 计算面积:
      • mid 是当前弹出的柱子下标。
      • w = i - st.top() - 1 是矩形的宽度。
      • h = heights[mid] 是矩形的高度。
      • 更新 result 为最大值。
  4. 返回结果:

    • 返回 result,即最大矩形的面积。

代码二:

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int ans = 0;stack<int> st;heights.insert(heights.begin(), 0);heights.push_back(0);st.push(0);for(int i = 1; i < heights.size(); ++i) {if(heights[i] >= heights[st.top()]) st.push(i);else {while(!st.empty() && heights[i] < heights[st.top()]) {int mid = st.top();st.pop();if(!st.empty()) {int left = st.top();int right = i;int w = right - left - 1;int h = heights[mid];ans = max(ans, w * h);}}st.push(i);}}return ans;}
};

消耗二:

image

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

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

相关文章

深入理解双变量(二元)正态投影:理论基础、直观解释与应用实例

在统计学和机器学习中,理解变量之间的关系对于构建预测模型和分析数据至关重要。探索这些关系的一种基本技术是双变量投影 bivariate projection。它依赖于二元正态分布的概念,所以又被称为二元投影。这种技术允许我们根据另一个变量来检验和预测一个变量的行为,利用它们之间的…

校验和

1. 对应数据位累加和: 需确认协议规定是从哪一位累加到哪一位,以及对应到代码中rd_cnt[7:0]是从第几位累加到第几位。//校验和 reg [15:0] rcvCLJ_SUM; always @(posedge SYS_CLK or negedge sys_rst_n ) beginif(!sys_rst_n) rcvCLJ_SUM <= 16d0;else if(rd_cnt>8d2 &…

Docker 入门文档阅读笔记

Docker 的架构图片来自 Docker 官网教程 Docker 采用 CS 架构, 可以通过 CLI 和 API 与 Docker daemon 进行交互。 Docker Objects Images (镜像) An image is a read-only template with instructions for creating a Docker container. Often, an image is based on anothe…

顶尖待办事项软件对比:找到你的最佳匹配

国内外主流的10款待办事项管理软件对比:PingCode、WorktileTodoist、TickTick、Teambition、 Microsoft To Do、. Asana、Tower、番茄ToDo、飞书。在面对日益复杂的工作和个人任务时,找到一款能够有效帮助你管理日常待办事项的软件,变得越来越重要。无论是在提高个人生产力,…

Oracle RAC 集群启动顺序 转发:https://www.modb.pro/db/1824295923545612288?utm_source=index_ori

前言 前几天使用脚本在 RockyLinux 9.4 安装 Oracle 11GR2 RAC,安装完之后发现集群无法正常启动,后经过分析发现原来是因为 RHEL9 版本默认安装移除了 initscripts 软件包,需要人为手动安装,在 RHEL8 之前是默认安装的。 在分析问题的过程中,顺便对 Oracle RAC 集群启动顺…

SHELL之数值运算

【四则运算符号】表达式 举例$(( )) echo $((1+1))$[ ] echo $[10-5]expr expr 10 / 5 (运算符左右有空格)let n=1;let n+=1 等价于 let n=n+1一、整数运算 1、基本运算类别加法:+ 减法:- 乘法:* 整除:/ 取余数:%2、expr运算工具加法:+ 减法:- 乘法:* 整除:/ 取余数…

FIFO读数取数

FIFO:先进先出的缓存器。常应用于带宽不同或者跨时钟域等数据传输情况。 相关参数:数据宽度,存储深度,将空标志位。空标志位。将满标志位,满标志位。读写时钟。其中将满信号与将空信号相较于真正的满信号与空信号都会提前一个时钟周期拉高。FIFO generator配置注意事项:B…

如何使用midjourney?MidJourney订阅计划及国内订阅教程

MidJourney订阅计划 MidJourney提供四种不同的订阅计划:订阅计划 每月费用 年度费用 使用限制基础计划 $10/月 $96/年($8/月) 每月可生成200张图,无fast模式,不能免排队生成图标准计划 $30/月 $288/年($24/月) 每月可无限量生成图片,15小时fast模式,免排队生成图,有隐…

寻访中国100家.NET中大企业 —— 第二站:苏州行

一:事情起因 在.NET圈里混了十多年,相信有不少人知道我专注于玩 .NET高级调试,如今技术上的硬实力还是能够解决市面上的一些疑难杂症,但软实力却在另一个极端,如(人际交往,人情事故),所以就萌生了刻意训练的念头,便自我发起了这个活动 "寻访中国100家.NET中大企…

7zip如何使带中文的文件名以utf-8编码?

问题: 在win 上压缩中文模版文件后,在Linux 上解压乱码 解决方案: 7-zip压缩的zip文件里面带有中文文件名的,在其他平台上解压后中文文件名乱码。在网上查找了下资料,使用7-zip压缩zip文件,可以使用参数cu=on,强制文件名以utf-8格式编码,在其他平台上解压后正常。 下图…

Windows 10、Windows 11 配置 gradle8

Windows 10、Windows 11 配置 gradle8GRADLE_HOME=D:\development\gradle\gradle-8.8GRADLE_USER_HOME=D:\\repository\\gradle-repository%GRADLE_HOME%\bin

windows环境Jenkins部署前端项目

在Windows环境下使用Jenkins部署前端项目,可以按照以下步骤进行: 1. 安装Jenkins可以从Jenkins官网下载Windows版本的Jenkins安装包。 安装完成后,启动Jenkins服务,并通过浏览器访问 http://localhost:8080 进入Jenkins管理界面。 windows环境Jenkins部署前端项目2. 配置Je…