代码随想录Day40-单调栈:力扣第496e、503m、42h、84h题

2023-10-30 23:30

本文主要是介绍代码随想录Day40-单调栈:力扣第496e、503m、42h、84h题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

496e. 下一个更大元素 I

题目链接
代码随想录文章讲解链接

方法一:单调栈+哈希表

用时:13m52s

思路

维护一个栈底到栈顶是单调递减的栈,从后往前遍历数组nums2,更新栈。nums2当前元素nums2[i]的下一个更大元素就是栈顶元素,若栈顶为空则表示nums2[i]之后没有比他大的元素。用哈希表存储,然后遍历nums1时再从哈希表中获取值。

  • 时间复杂度: O ( m + n ) O(m+n) O(m+n)
  • 空间复杂度: O ( m + n ) O(m+n) O(m+n)
C++代码
class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {stack<int> stk;unordered_map<int, int> hashMap;vector<int> res(nums1.size(), 0);for (int i = nums2.size() - 1; i >= 0; --i) {while (!stk.empty() && nums2[i] > stk.top()) stk.pop();hashMap[nums2[i]] = stk.empty() ? -1 : stk.top();stk.push(nums2[i]);}for (int i = 0; i < res.size(); ++i) res[i] = hashMap[nums1[i]];return res;}
};

看完讲解的思考

无。

代码实现遇到的问题

无。


503m. 下一个更大元素II

题目链接
代码随想录文章讲解链接

方法一:单调栈

用时:16m28s

思路

维护一个栈底到栈顶单调递减的单调栈,遍历两遍数组。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {int size = nums.size();stack<int> stk;vector<int> res(size, -1);for (int i = 0; i < size * 2; ++i) {while (!stk.empty() && nums[stk.top()] < nums[i % size]) {res[stk.top()] = nums[i % size];stk.pop();}stk.push(i % size);}return res;}
};

看完讲解的思考

无。

代码实现遇到的问题

无。


42h. 接雨水

题目链接
代码随想录文章讲解链接

方法一:按列统计

用时:28m51s

思路

分别统计每一列雨水的高度,设某一列i左边最高的柱子高度为L,列i右边最高的柱子高度为R,若min(L,R)大于列i的高度,则列i的雨水量为min(L,R) - height[i],否则为0。
先分别记录下每个位置左右两边最高的柱子的高度,然后再统计每一列雨水的高度。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
public:int trap(vector<int>& height) {int size = height.size();vector<int> leftMax(size, 0);vector<int> rightMax(size, 0);int maxHeight = 0;int res = 0;// 记录每个位置左右两边最高的柱子高度for (int i = 0; i < size; ++i) {leftMax[i] = maxHeight;maxHeight = max(maxHeight, height[i]);}maxHeight = 0;for (int i = size - 1; i >= 0; --i) {rightMax[i] = maxHeight;maxHeight = max(maxHeight, height[i]);}// 统计每一列的雨水for (int i = 1; i < size - 1; ++i) {int minHeight = min(leftMax[i], rightMax[i]);if (minHeight > height[i]) res += minHeight - height[i];}return res;}
};

方法二:单调栈按行统计

用时:13m28s

思路

维护一个栈底到栈顶单调递减的单调栈。
遍历数组的时候,若遇到小于等于栈顶元素的元素,则直接入栈。
若遇到大于栈顶元素的元素,此时栈顶元素作为凹陷处,倒数第二个栈顶元素和当前元素作为两头的柱子,可以形成一个坑接住雨水,接住雨水的量等于(min(height[i], height[stk.top()]) - height[mid]) * (i - stk.top() - 1),分别是高乘宽。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
public:int trap(vector<int>& height) {stack<int> stk;int res = 0;for (int i = 0; i < height.size(); ++i) {while (!stk.empty() && height[i] > height[stk.top()]) {int mid = stk.top();stk.pop();if (!stk.empty()) res += (min(height[i], height[stk.top()]) - height[mid]) * (i - stk.top() - 1);}stk.push(i);}return res;}
};

看完讲解的思考

无。

代码实现遇到的问题

无。


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

题目链接
代码随想录文章讲解链接

方法一:三次遍历

用时:18m4s

思路

以某个柱子为基准,最大矩形面积与该柱子两侧第一个比它矮的柱子的位置有关。
前两次遍历找到每个柱子左右两侧第一个比它矮的柱子的位置。
最后一次遍历计算以各个柱子为基准的最大矩形面积,最大值即为答案。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
public:int largestRectangleArea(vector<int>& heights) {int size = heights.size();vector<int> leftMin(size);vector<int> rightMin(size);int res = 0;// 记录每个柱子左边第一个比它小的柱子的位置leftMin[0] = -1;for (int i = 1; i < size; ++i) {int left = i - 1;while (left >= 0 && heights[left] >= heights[i]) left = leftMin[left];leftMin[i] = left;}// 记录每个柱子右边第一个比它小的柱子的位置rightMin[size - 1] = size;for (int i = size - 2; i >= 0; --i) {int right = i + 1;while (right < size && heights[right] >= heights[i]) right = rightMin[right];rightMin[i] = right;}// 遍历以每个柱子为基准的矩形大小,记录最大值for (int i = 0; i < size; ++i) res = max(res, heights[i] * (rightMin[i] - leftMin[i] - 1));return res;}
};

方法二:单调栈

用时:33m9s

思路

因为我们要找到某个基准柱子左右两边比它小的柱子的位置,所以药维护一个栈底到栈顶单调递增的单调栈,这样对于栈顶元素的柱子,它左边第一个比它小的柱子就是第二个栈顶元素,右边第一个比它小的元素就是遍历过程中比栈顶元素小的元素。
遍历数组,若元素大于等于栈顶元素,则入栈;若元素小于栈顶元素,则取出栈顶元素作为基准柱子,然后弹出栈顶元素,基准柱子左边第一个比它小的柱子就是此时的栈顶元素,右边第一个比它小的柱子就是当前遍历的元素,然后记录矩形的面积并更新答案。
由于在遍历的过程中,可能会出现栈为空的情况,以及数组本身就是递增数组的情况,此时会有特殊情况需要处理,可以在数组前后各加入一个0,简化逻辑,因为0一定是小于柱子高度,能够作为左右两端最矮的基准柱子的边界。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
public:int largestRectangleArea(vector<int>& heights) {stack<int> stk;int res = 0;heights.insert(heights.begin(), 0);heights.push_back(0);stk.push(0);for (int i = 1; i < heights.size(); ++i) {while (heights[i] < heights[stk.top()]) {int mid = stk.top();stk.pop();res = max(res, heights[mid] * (i - stk.top() - 1));}stk.push(i);}return max(res, heights[stk.top()]);}
};

看完讲解的思考

无。

代码实现遇到的问题

边界问题处理了半天没搞定,在数组前后各加入一个0的方法真巧妙。


最后的碎碎念

最近都在搞比赛,好久没刷题了,比赛目前搞得差不多了,得接着刷题了。
希望比赛能拿个好成绩,求求求求求求了!

这篇关于代码随想录Day40-单调栈:力扣第496e、503m、42h、84h题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/311264

相关文章

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot实现图形验证码的示例代码

《SpringBoot实现图形验证码的示例代码》验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用Hutool提供的小工具实现,本文介绍Sp... 目录项目创建前端代码实现约定前后端交互接口需求分析接口定义Hutool工具实现服务器端代码引入依赖获

利用Python在万圣节实现比心弹窗告白代码

《利用Python在万圣节实现比心弹窗告白代码》:本文主要介绍关于利用Python在万圣节实现比心弹窗告白代码的相关资料,每个弹窗会显示一条温馨提示,程序通过参数方程绘制爱心形状,并使用多线程技术... 目录前言效果预览要点1. 爱心曲线方程2. 显示温馨弹窗函数(详细拆解)2.1 函数定义和延迟机制2.2

Springmvc常用的注解代码示例

《Springmvc常用的注解代码示例》本文介绍了SpringMVC中常用的控制器和请求映射注解,包括@Controller、@RequestMapping等,以及请求参数绑定注解,如@Request... 目录一、控制器与请求映射注解二、请求参数绑定注解三、其他常用注解(扩展)四、注解使用注意事项一、控制

C++简单日志系统实现代码示例

《C++简单日志系统实现代码示例》日志系统是成熟软件中的一个重要组成部分,其记录软件的使用和运行行为,方便事后进行故障分析、数据统计等,:本文主要介绍C++简单日志系统实现的相关资料,文中通过代码... 目录前言Util.hppLevel.hppLogMsg.hppFormat.hppSink.hppBuf

VS Code中的Python代码格式化插件示例讲解

《VSCode中的Python代码格式化插件示例讲解》在Java开发过程中,代码的规范性和可读性至关重要,一个团队中如果每个开发者的代码风格各异,会给代码的维护、审查和协作带来极大的困难,这篇文章主... 目录前言如何安装与配置使用建议与技巧如何选择总结前言在 VS Code 中,有几款非常出色的 pyt

利用Python将PDF文件转换为PNG图片的代码示例

《利用Python将PDF文件转换为PNG图片的代码示例》在日常工作和开发中,我们经常需要处理各种文档格式,PDF作为一种通用且跨平台的文档格式,被广泛应用于合同、报告、电子书等场景,然而,有时我们需... 目录引言为什么选择 python 进行 PDF 转 PNG?Spire.PDF for Python

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工