深入理解单调栈及其应用:以LeetCode-Py项目为例
1. 单调栈基础概念
单调栈是一种特殊的栈结构,它在普通栈的"后进先出"特性基础上,增加了元素单调性的约束。根据单调性的不同,单调栈可以分为两种主要类型:
1.1 单调递增栈
单调递增栈要求从栈顶到栈底的元素保持递增顺序。这种栈的特点是:
- 新元素入栈前,会移除栈中所有比它小的元素
- 栈顶元素始终是当前栈中最小的元素
- 适合解决"寻找左侧/右侧第一个更大元素"的问题
操作流程:
- 当新元素小于栈顶元素时,直接入栈
- 当新元素大于等于栈顶元素时,弹出栈顶元素直到满足条件1
- 将新元素压入栈中
1.2 单调递减栈
单调递减栈要求从栈顶到栈底的元素保持递减顺序。这种栈的特点是:
- 新元素入栈前,会移除栈中所有比它大的元素
- 栈顶元素始终是当前栈中最大的元素
- 适合解决"寻找左侧/右侧第一个更小元素"的问题
操作流程:
- 当新元素大于栈顶元素时,直接入栈
- 当新元素小于等于栈顶元素时,弹出栈顶元素直到满足条件1
- 将新元素压入栈中
2. 单调栈的核心应用场景
单调栈主要用于解决一类特定的问题:在序列中快速找到每个元素左右两侧第一个满足某种条件的元素。具体来说,它可以高效解决以下四类问题:
2.1 寻找左侧第一个更大元素
使用单调递增栈,从左向右遍历:
- 入栈时栈顶元素即为左侧第一个更大的元素
- 栈为空表示左侧没有更大的元素
2.2 寻找左侧第一个更小元素
使用单调递减栈,从左向右遍历:
- 入栈时栈顶元素即为左侧第一个更小的元素
- 栈为空表示左侧没有更小的元素
2.3 寻找右侧第一个更大元素
有两种实现方式:
-
使用单调递增栈,从左向右遍历:
- 元素被弹出时,导致它弹出的元素就是右侧第一个更大的元素
- 未被弹出的元素表示右侧没有更大的元素
-
使用单调递增栈,从右向左遍历:
- 入栈时栈顶元素即为右侧第一个更大的元素
- 栈为空表示右侧没有更大的元素
2.4 寻找右侧第一个更小元素
同样有两种实现方式:
-
使用单调递减栈,从左向右遍历:
- 元素被弹出时,导致它弹出的元素就是右侧第一个更小的元素
- 未被弹出的元素表示右侧没有更小的元素
-
使用单调递减栈,从右向左遍历:
- 入栈时栈顶元素即为右侧第一个更小的元素
- 栈为空表示右侧没有更小的元素
3. 单调栈的通用模板
3.1 单调递增栈模板
def increasing_stack(nums):
stack = []
for num in nums:
# 维护栈的单调性:弹出所有小于当前元素的栈顶元素
while stack and num > stack[-1]:
stack.pop()
stack.append(num)
3.2 单调递减栈模板
def decreasing_stack(nums):
stack = []
for num in nums:
# 维护栈的单调性:弹出所有大于当前元素的栈顶元素
while stack and num < stack[-1]:
stack.pop()
stack.append(num)
4. 经典问题解析
4.1 下一个更大元素问题
问题描述:给定两个数组nums1和nums2,其中nums1是nums2的子集。对于nums1中的每个元素,找到它在nums2中对应位置右侧第一个更大的元素。
解题思路:
- 使用单调递增栈预处理nums2,建立元素与其下一个更大元素的映射
- 遍历nums1,直接从映射表中查询结果
关键点:
- 单调栈帮助我们以O(n)时间复杂度建立映射关系
- 哈希表存储中间结果,实现快速查询
4.2 每日温度问题
问题描述:对于每天的温度,计算需要等待多少天才能遇到更高的温度。
解题思路:
- 使用单调递减栈存储日期索引
- 当遇到更高温度时,计算日期差并更新结果数组
- 栈中剩余元素表示没有更高温度的日子
优化点:
- 直接存储索引而非温度值,便于计算天数差
- 结果数组初始化为0,无需处理栈中剩余元素
5. 算法复杂度分析
单调栈算法的时间复杂度通常为O(n),其中n是输入数组的长度。这是因为:
- 每个元素最多入栈一次、出栈一次
- 虽然存在嵌套循环,但内层while循环的总操作次数不会超过n次
空间复杂度一般为O(n),主要用于存储栈结构和结果。
6. 实际应用中的注意事项
- 元素相等处理:根据问题需求决定是否保留相等元素
- 边界条件:空输入、所有元素相同等特殊情况
- 索引与值:根据问题选择存储值还是索引
- 遍历方向:从左到右或从右到左会影响求解逻辑
单调栈是一种强大而高效的数据结构,特别适合处理"邻近更大/更小元素"类问题。通过LeetCode-Py项目中的这些经典问题,我们可以深入理解其工作原理和应用技巧。掌握单调栈不仅能够提升算法解题能力,也能帮助我们更好地处理实际开发中的类似问题。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考