算法学习之单调栈详解
创作时间:
作者:
@小白创作中心
算法学习之单调栈详解
引用
CSDN
1.
https://m.blog.csdn.net/black_cat7/article/details/143107402
单调栈的基本概念和作用
什么是单调栈?
单调栈是指栈内元素保持单调递增或单调递减顺序的一种栈结构。这种特性使得单调栈在解决某些特定类型的问题时表现出色,如寻找下一个更大或更小的元素、区间查询等。
单调栈的作用
单调栈主要用于解决以下几类问题:
- 寻找数组中每个元素的下一个更大或更小的值。
- 在一个序列中快速定位满足特定条件的最长或最短子序列。
- 处理区间最大最小值问题。
示例代码
示例一:寻找下一个更大的元素
给定两个没有重复元素的数组 nums1
和 nums2
,其中 nums1
是 nums2
的子集。对于 nums1
中的每一个数,在 nums2
中找到这个数右边的第一个比它大的数。如果不存在,则输出 -1。
def nextGreaterElement(nums1, nums2):
stack = [] # 用于存放遍历过的元素
map = {} # 存放结果的映射
for num in nums2:
while stack and stack[-1] < num:
map[stack.pop()] = num
stack.append(num)
return [map.get(n, -1) for n in nums1]
示例二:直方图中最大的矩形面积
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨后能接多少雨水。
def largestRectangleArea(heights):
heights.append(0) # 添加哨兵
stack = [-1] # 初始化栈,哨兵
result = 0
for i, h in enumerate(heights):
while heights[stack[-1]] > h:
height = heights[stack.pop()]
width = i - stack[-1] - 1
result = max(result, height * width)
stack.append(i)
return result
示例三:寻找左边第一个小于当前元素的位置
给定一个整数数组,返回一个新的数组,新数组中的每个元素为原数组中该元素左边第一个小于它的元素的位置,如果没有则为 -1。
def leftSmaller(nums):
stack = []
result = [-1] * len(nums)
for i, num in enumerate(nums):
while stack and nums[stack[-1]] >= num:
stack.pop()
if stack:
result[i] = stack[-1]
stack.append(i)
return result
示例四:寻找右边第一个大于当前元素的位置
与寻找左边第一个小于当前元素的位置类似,这里的目标是找到每个元素右边第一个大于它的元素的位置。
def rightLarger(nums):
stack = []
result = [len(nums)] * len(nums) # 默认值设为数组长度,表示不存在
for i in reversed(range(len(nums))):
while stack and nums[stack[-1]] <= nums[i]:
stack.pop()
if stack:
result[i] = stack[-1]
stack.append(i)
return result
示例五:股票的最佳买卖时机
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来找出你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。但是,你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
def maxProfit(prices):
stack = []
profit = 0
for price in prices:
while stack and stack[-1] > price:
profit += stack[-1] - stack.pop(0)
stack.append(price)
while stack:
profit += stack[-1] - stack.pop(0)
return profit
实际工作中的应用技巧
在实际开发中,正确选择数据结构和算法对于提高程序效率至关重要。单调栈因其高效的特性和简洁的实现方式,在很多场景下都能发挥重要作用。然而,使用单调栈时也需要注意以下几点:
- 边界条件:处理好边界情况,例如数组为空或只有一个元素时的行为。
- 栈的选择:根据具体需求选择合适类型的栈,如列表或链表形式。
- 性能优化:对于大规模数据处理,可以通过预分配栈的容量等方式来减少内存分配带来的开销。
- 错误处理:编写健壮的错误处理逻辑,确保即使在异常情况下也能优雅地恢复。
综上所述,单调栈作为一种高效的算法工具,值得每一位开发者深入了解并熟练掌握。通过本文提供的示例和讨论,希望能帮助读者在遇到相关问题时能够灵活运用单调栈技术。
热门推荐
如何申请公益律师援助的具体条件
FreeRTOS消息队列详解:概念、API与实现原理
地暖管材选购指南:三种主流材质的优劣分析与选购建议
PPR管与铝塑管的区别是什么?
视频监控制度是什么(视频监控管理办法职责)
【婴配奶粉】降低牛乳致敏的关键要点——水解乳蛋白
基于STM32单片机的物联网远程WiFi控制智能定时LED台灯设计
如何理解K线图的构成要素和分析方法?这些要素和方法如何辅助投资决策?
治疗类风湿关节炎的用药时长,取决于这3方面
解读《2024中国类风湿关节炎诊疗指南》
黑科技还是智商税?专家提醒→
全球五大摩托车赛事:速度与激情的极致碰撞
清朝祖训后宫不得干政,为何慈溪还能垂帘听政,统治大清几十年
RO膜反渗透滤芯工作原理是什么
肺部痰多怎么办
揭秘《柳舟记》柳眠棠家族背景!李世民都要客套 武则天拼命打压
Delta动态对冲:期权市场中的风险管理艺术
诸“子”安徽 | 上善若水
数据编织与ETL:优化数据流以提升分析效率300%
烤面包温度多少烤几分钟?不同种类面包烤制指南
建议睡觉时把手机放1.5米以外?不是因为辐射,而是→
合同违约拖欠费用怎么办?法律详解与处理步骤
有之以为利,无之以为用:无的哲学智慧与现实意义丨道德经11章
DIY组装机真的比整机贵?深度解析硬件成本与性价比的博弈
身体出现这5种疼痛,可能是疾病来临,要及时就诊
mcg是什么单位?了解mcg在测量中的应用与含义
AIGC对哪些行业影响最大?能否替代人类进行创作?
零基础学习英语语法的技巧
伊犁文物:历史的见证者
低配电脑畅玩《黑神话:悟空》的完整攻略