代码随想录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

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所