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

杭州网站建设派迪网络5118站长工具箱

杭州网站建设派迪网络,5118站长工具箱,php培训网站源码,初次安装宽带要多少钱单调栈应用介绍 定义应用场景实现模板具体示例下一个最大元素I问题描述问题分析代码实现柱状图中最大的矩形问题描述问题分析代码实现接雨水问题描述问题分析代码实现最大宽度坡问题描述问题分析代码实现132模式问题描述问题分析代码实现定义 栈(Stack)是另一种操作受限的线性…

单调栈应用介绍

  • 定义
  • 应用场景
  • 实现模板
  • 具体示例
    • 下一个最大元素I
      • 问题描述
      • 问题分析
      • 代码实现
    • 柱状图中最大的矩形
      • 问题描述
      • 问题分析
      • 代码实现
    • 接雨水
      • 问题描述
      • 问题分析
      • 代码实现
    • 最大宽度坡
      • 问题描述
      • 问题分析
      • 代码实现
    • 132模式
      • 问题描述
      • 问题分析
      • 代码实现

定义

栈(Stack)是另一种操作受限的线性表,只允许元素从栈的顶端进顶端出,具有后进先出(LIFO)的特性。但单调栈(Monotonic Stack)是一种特殊的栈,在满足栈特性的基础上,栈内元素从栈底到栈顶具有单调性。如果栈底到栈顶元素是单调递减,则称为单调递减栈;如果栈底到栈顶元素是单调递增,则称为单调递增栈。

单调栈具有以下特性:

  • 新元素加入栈顶时,需要进行单调性维护,弹出不满足单调性的栈顶元素
  • 当前解计算是在出栈的时候进行的

应用场景

  • 下一个最大元素,对应单调递减栈
  • 下一个最小元素,对应单调递增栈
  • 上一个最大元素,反向入栈,即从数据尾部往前遍历,对应单调递减栈
  • 上一个最小元素,反向入栈,即从数据尾部往前遍历,对应单调递增栈

以上是单调栈最基础的应用场景,很多问题也是对这些场景的变种,我们需要一针见血的直指问题核心。

实现模板

在代码实现上,主要涉及两个动作(动作之间的顺序需要根据具体问题场景灵活调整):

  • 维护栈顶: 保证整个栈的单调性,新元素入栈时,及时弹出栈顶不满足单调性的元素
  • 问题解计算逻辑:在弹出栈顶时,计算问题解

伪代码如下:

ans = 问题初始解
//tips:由于下面流程必须判断栈非空,某些场景下,可以构造一个不影响结果又能保证栈永远非空的初始化栈,这样就避免判断栈非空逻辑 ---  
stack<栈内元素类型> stk = 初始化栈;
//正常处理流程
for(const auto& item: dataSource){while (!stk.empty() && checkMonotonic(stk.top(), item)) {//计算问题解ans = 问题解计算逻辑stk.pop();}stk.push(x);
}//在某些场景下,需要保证所有元素出栈 --- 可以通过一些辅助数据来 保证所有数据在上面流程中全部出栈,这样可以省略以下逻辑,保证代码简洁性
while (!stk.empty()) {//计算问题解ans = 问题解计算逻辑stk.pop();
}

单调栈的结构简单,应用形式灵活,需要结合具体问题灵活处理。

具体示例

下一个最大元素I

496. 下一个更大元素 I

问题描述

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧第一个 比 x 大的元素。
给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

示例 1

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。

示例 2

输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。

问题分析

本题的问题描述看着挺复杂的,但由于nums1是nums2的子集,即nums1中的数值都在nums2中,且无重复数字,所以,这里的问题可以简化先为求nums2中每个元素的下一个最大元素,然后再取nums1中特定元素对应的下一个最大元素。

代码实现

class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {//适用hash map存储每个元素对应的下一个最大元素值unordered_map<int,int> preData;stack<int> stk;//使用单调递减栈求取每个元素的下一个最大元素for(int idx = nums2.size() - 1; idx >= 0; --idx){while(!stk.empty() && nums2[idx] >= stk.top()){stk.pop();}preData[nums2[idx]] = stk.empty() ? -1 : stk.top();stk.push(nums2[idx]);}vector<int> ans;//遍历每个元素取值for(int num: nums1){ans.push_back(preData[num]);}return ans;}
};

柱状图中最大的矩形

84. 柱状图中最大的矩形

问题描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:
在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2
在这里插入图片描述

输入: heights = [2,4]
输出: 4

问题分析

矩形面积的计算公式为 矩形面积 = 宽 ∗ 高 矩形面积= 宽 * 高 矩形面积=,求最大面积需要遍历所有柱子,以该柱子为高的所有矩形面积中的最大面积。当计算某根柱子为高的矩形面积时,只需要确定宽度,即确定矩形的左右边界:

  • 左边界:该柱子往左找到第一个比他矮的柱子
  • 右边界:该柱子往右找到第一个比他矮的柱子

矩形最大面积
对应的代码实现如下:

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int ans = 0;int size = heights.size();for(int idx = 0; idx < size; ++idx){//查找左边界:往左找第一个比他矮的柱子int left = idx;while(left > 0 && heights[left - 1] >= heights[idx]) left--;//查找右边界:往右找第一个比他矮的柱子int right = idx;while(right < size - 1 && heights[right + 1] >= heights[idx]) right++;ans = max(ans, heights[idx] * (right - left + 1));}return ans;}
};

这道题作为难度级别为Hard的题目,该实现提交后肯定会超时,超时的原因就是在确定左右边界时会做大量的来回比较,如果我们能够快速找到左右边界,那就ok了。在确定左右边界时,需要找到第一个比他矮的柱子,这不这是单调队列的经典应用场景吗?

对于该问题,需要往左和往右两个方向利用单调递增栈求其第一个比他矮的柱子。

代码实现

先利用单调递增栈分别求出当前柱子的左右边界,然后再计算所有柱子对应的矩形面积,最后取其中最大的矩形面积。

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int size = heights.size();stack<int> stk;//左边界vector<int> left(size,0);for(int idx = 0; idx < size; ++idx){while(!stk.empty() && heights[stk.top()] >= heights[idx]) stk.pop();left[idx] = stk.empty() ? -1 : stk.top();stk.push(idx);}stk = stack<int>();//右边界vector<int> right(size,0);for
http://www.tj-hxxt.cn/news/1253.html

相关文章:

  • excel表如何做网站连接百度检索入口
  • 情侣做记录网站源码企业网站建设模板
  • 上海网站建设基础东莞seo优化排名
  • x网站免费模板免费下载网页推广怎么做的
  • 公司注册流程2020seo在线外链
  • 用html做家谱网站代码中国网站建设公司前十名
  • 帝国cms这么做网站运营网站
  • 哪些网上订餐的网站做的好好的seo网站
  • 制作网站费用seo课程培训入门
  • 珠海市建设局官方网站品牌策划方案范文
  • 网站引导页动态效果怎么做的外链发布工具
  • 做网站徐州营销型网站开发公司
  • 青岛靠谱的做网站公司建网站专业
  • 2020电商网站排行榜上海推广网站
  • 自己做赌博网站百度首页百度
  • 高唐网页定制seo技术分享博客
  • 旅游网站排行榜前十名官网百度投诉电话24小时
  • 苏州网站开发公司鹅鹅鹅优化排名工具
  • wordpress4.5 下拉菜单网站在线优化检测
  • 属于c2c的网站有哪些湖南专业的关键词优化
  • 重庆整合营销网站建设推广怎么推
  • 品牌高端网站制作机构北京seo公司工作
  • 网站还是app关键词推广技巧
  • 卖视频会员个人网站怎么做最新seo自动优化软件
  • 网站分为几种类型深圳市前十的互联网推广公司
  • 优化方案2021版英语seo搜索引擎工具
  • 做二手房网站有哪些资料3000块钱在朋友圈投放广告
  • 网站静态图怎么做公司网站建设多少钱
  • 界面设计图枫林seo工具
  • 企业做网站营销seo软文推广工具