什么是单调栈?

栈是先进后出的一种数据结构,而单调栈即无论何时栈中存放的数据是有序的,分为单调递增栈和单调递减栈

  • 单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小
  • 单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大

应用

leetcode中用很多题目都可以用单调栈来解决,用python来实现,用列表list来模拟栈。以下题目都是使用的单调递增栈。

获取数组中每个元素的下一个更大元素

例如,获取[1, 3, 4, 2]中每个元素的更大值,如果不存在返回-1,结果为[3, 4, -1, -1]

class Solution:def nextGreaterElement(self, nums):if len(nums) == 0: return []res = []stack = []length = len(nums)for j in range(length - 1, -1, -1):while len(stack) != 0 and stack[-1] < nums[j]:stack.pop()if len(stack) == 0:cur = - 1else:cur = stack[-1]res.append(cur)stack.append(nums[j])res.reverse()return res
  1. 列表元素从后往前遍历,这样每次在栈中的元素都是在当前元素之后的。
  2. 不断将栈顶小于当前元素的值pop出来,如果最后栈中还有元素,则栈顶元素是当前元素的下一个更大的值,如果栈为空,则不存在下一个更大元素。(不会影响第i-1个元素的处理,因为pop出来的是比当前元素i小,并且在当前元素i的后面的元素,不可能称为第i-1个元素的结果)
  3. 将当前元素放入栈中,处理下一个元素。

496. 下一个更大元素 I

与上题解法相同,只是需要一个额外的空间来记录,nums1中每个数对应的索引。通过单调栈处理nums2,得到nums2中所有元素的下一个更大元素。然后将出现在nums1中的元素的下一个更大元素放在res对应的位置。

class Solution:def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:if len(nums1) == 0 or len(nums2) == 0 : return []# 记录nums1数组中,包含的数的索引num1_dict = {nums1[i]:i for i in range(len(nums1))}res = [-1]*len(nums1)stack  = []len2 = len(nums2)for j in range(len2-1,-1,-1):while len(stack) != 0 and stack[-1] < nums2[j]:stack.pop()if len(stack) == 0:cur = - 1else:cur = stack[-1]if nums2[j] in num1_dict:index = num1_dict[nums2[j]]res[index] = curstack.append(nums2[j])return res

时间复杂度:O(len(nums1))
空间复杂度:O(len(nums2) + len(nums1))

503. 下一个更大元素 II


循环数组,最后一个元素额下一个更大元素不再是-1,通过复制一遍数组来解决循环数组的问题

class Solution:def nextGreaterElements(self, nums: List[int]) -> List[int]:if len(nums) == 0:return numstmp_nums = nums + numsnum = len(tmp_nums)stack = []res = []for i in range(num - 1, -1, -1):while len(stack)!=0 and stack[-1] <= tmp_nums[i]:stack.pop()if len(stack) == 0:cur = -1else:cur = stack[-1]if i < num // 2:res.append(cur)stack.append(tmp_nums[i])res.reverse()return res

时间复杂度:O(2n)
空间复杂度:O(n)

739. 每日温度

这里不是求下一个更大的元素,而是求与下一个更大的元素相隔几天,因此,存入栈中的是当前元素的索引

class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:if len(temperatures) == 0:return temperaturesnum = len(temperatures)res = []stack = [] # 存入索引for i in range(num-1,-1,-1):while len(stack) !=0 and temperatures[stack[-1]] <= temperatures[i]:stack.pop()if len(stack) == 0:res.append(0)else:index = stack[-1]res.append(index - i)stack.append(i)res.reverse()return res

时间复杂度:O(n)
空间复杂度:O(n)

还有其他一些更加复杂的题目需要用到单调栈,例如leetcode 84,leetcode 739,leetcode 1673

python解决单调栈问题相关推荐

  1. 【栈】python、单调栈解决收集雨水问题、力扣42题

    以下是leetcode 42原题: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1 ...

  2. 将一个数组中的值按逆序重新排放。_六十五、下一个更大的数系列,单调栈解决方法...

    「@Author:Runsen」 ❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. 「---- Runsen」 ❞ 据说,放张小姐姐觉得照片可以提高阅读量,图是来源学校 ...

  3. 单调栈解决维持相对位置不变最小/最大字典序问题

    多次碰到这类维持相对位置不变,删除某些元素维持最小or最大字典序问题,这里记录一下: 首先给出一个经典的例子: 我们想要维持最小或者最大,无非是要保持相对有序的情况下,保持一个递增或者递减栈,其实就是 ...

  4. 2022-11-16 每日打卡:单调栈解决最大矩形问题(一维直方图,二维最大红矩形)

    每日打卡:单调栈解决最大矩形问题(一维直方图,二维最大红矩形) 柱状图中最大的矩形 思路 这个题最明显的思路就是:矩形面积=底×高. 版本1:底的长度可以通过二重循环来完成,高通过循环来寻找最小值. ...

  5. 使用单调栈解决接雨水问题——LeetCode 42 接雨水+单调栈说明

    题目内容 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输 ...

  6. 单调栈解决取矩形问题

    单调栈解决取矩形问题 ​ 前言:这一类问题不知道是什么问题,emmm大概意思就是从一个混合着可行点和不可行点的矩形中能取出的充满可行点的矩形的数目.这一类问题应该有一个官方的名字,大家如果知道可以在评 ...

  7. 六十五、下一个更大的数系列,单调栈解决方法

    @Author:Runsen 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. ---- Runsen 据说,放张小姐姐觉得照片可以提高阅读量,图是来源学校的2020新生. ...

  8. 的input最大长度_LeetCode 84 | 单调栈解决最大矩形问题

    今天是LeetCode专题第52篇文章,我们一起来看LeetCode第84题,Largest Rectangle in Histogram(最大矩形面积). 这道题的官方难度是Hard,点赞3581, ...

  9. 洛谷P4147 玉蟾宫(单调栈解决)

    题目 题目链接 题目背景 有一天,小猫 rainbow 和 freda 来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 题目描述 这片土地被分成 N\times ...

最新文章

  1. python中怎么做分组问题_详解Python中的分组函数groupby和itertools)
  2. linux 命令改配置文件,linux下 修改配置文件的命令
  3. c#中中读取嵌入和使用资源文件的方法
  4. Codeforces Round #727 (Div. 2) 题解
  5. 列名 userid 不明确。 表结构_那些你不知道的表结构设计思路
  6. java-设计模式(结构型)-【代理模式】
  7. reshape [] matlab,matlab reshape函数
  8. C++ string与vectorfloat类型相互转换之stringstream
  9. 数字孪生智慧园区能源管理系统
  10. vfp中写入文本文件_VFP中操作多种文件
  11. 如何撰写数据中台蓝图方案
  12. matlab里添加白噪声,转Matlab中添加高斯白噪声
  13. Win10 安装node.js
  14. 微信小程序java美食厨房食谱大全分享系统
  15. 【Python基础】3-语法进阶
  16. 如何解析(读取)LZ4压缩格式的Spark EventLog日志
  17. Transporter提交app到App Store,“正在验证APP-正在通过App Store进行认证...”卡住或很慢的解决方案
  18. linux平台的字典,Linux系统中安装CLI的字典sdcv
  19. Vue2+Openlayer使用modify修改要素
  20. 模拟双色球机选的小程序

热门文章

  1. [物理学与PDEs]第1章习题7 载流线圈的磁场
  2. Android屏幕解锁和点亮
  3. iframe design=on 时,oncontextmeun不能触发之问题!
  4. php抓取dom处理后数据,PHP简单DOMDocument抓取排除td类
  5. html轮播图水平传送带,经典的白富美型jQuery图片轮播插件
  6. android访问服务器405,android – HTTP状态405 – 不允许的方法(jax-rs服务)
  7. 高性能游戏本搭服务器,为吃鸡而生,这几款高性能游戏本不容错过!
  8. 2批量批量查询数据插入数据_不吹牛!Mysql 千万数据10秒批量插入只需三步
  9. java中finaljava中this_Java中this,static,final,const用法详解
  10. dbvisivuser连oracle数据库报错没有权限