单调栈
单调栈里的元素是单调的。它的功能通常是:给定一个数组A
,对每个给定的索引i
,寻找数组中第一个大于(或小于)A[i]
的位置。
例如,我需要寻找数组中第一个大于A[i]
的位置,则使用递减单调栈。
假设给定的数组是[1,5,2,6,8,4]
,下标从0开始,我们很容易可以得到结果res=[1,3,3,4,-1,-1]
。
过程是这样的
第一个循环:1
入栈,此时stack=[1]
第二个循环:5
比栈顶元素1
要大,1
出栈,5
进栈,此时可以得到res[0]=1
,此时stack=[5]
第三个循环:2
比栈顶元素小,进栈,此时stack=[5,2]
。
第四个循环:6
比栈顶元素2
大,2
出栈,res[2]=3
,此时栈顶元素5
依然比6
小,5
出栈,res[1]=3
,最后6
入栈。此时stack=[6]
第五个循环:8
比栈顶元素6
大,6
出栈,8
入栈,res[3]=4
,此时stack=[8]
第六个循环:4
入栈,此时stack=[8,4]
,循环结束。
最后留在栈中的元素意味着在右边找不到比他更大的元素了。
正向实现
l = len(A)
# 初始化
res = [-1 for _ in range(l)]
# 在右边找比他第一个大的元素,stack是单调递减栈
stack = []
for i in range(l):
while stack and A[stack[-1]] <= A[i]:
res[stack.pop()] = i
stack.append(i)
反向实现
l = len(A)
# 初始化
res = [-1 for _ in range(l)]
# 在右边找比他第一个大的元素,stack是单调递减栈
for i in range(l-1,-1,-1):
# 这里的小于号等价于正向实现时所使用的小于等于
while stack and A[stack[-1]] < A[i]:
stack.pop()
if stack:
res[i] = stack[-1]
stack.append(i)
相关题目:Leetcode 496 503 739 901 1124 1130
参考:https://blog.csdn.net/qq_17550379/article/details/86519771