一、单调栈
一种特殊的栈,在栈的「先进后出」规则基础上,要求「从 栈顶 到 栈底 的元素是单调递增(或者单调递减)」。其中满足从栈顶到栈底的元素是单调递增的栈,叫做「单调递增栈」。满足从栈顶到栈底的元素是单调递减的栈,叫做「单调递减栈」。
单调递增栈:只有比栈顶元素小的元素才能直接进栈,否则需要先将栈中比当前元素小的元素出栈,再将当前元素出栈。结果:从栈顶到栈底的元素值是单调递增的。
单调自减栈:只有比栈顶元素大的元素才能直接进栈,否则需要先将栈中比当前元素大的元素出栈,再将当前元素入栈。
二、单调栈适用场景
单调栈可以在时间复杂度为O(n)的情况下,求解出某个元素左边或者右边第一个比它大或者小的元素。
口诀:
查找 「比当前元素大的元素」 就用 单调递增栈,查找「比当前元素小的元素」就用 单调递减栈。
从 「左侧」 查找就看 「插入栈」 时的栈顶元素,从 「右侧」 查找就看 「弹出栈」 时即将插入的元素。
二、代码模板
- 单调递增栈模板(栈底到栈顶单调递增)
def IncreasingStack(nums):
stack = []
for num in nums:
# 当前值大于栈顶元素,将栈顶元素弹出
while stack and num >= stack[-1]:
stack.pop()
stack.append(num)
- 单调递减模板(栈底到栈顶单调递减)
def DecreasingStack(nums):
stack = []
while stack and num <= stack[-1]:
stack.pop()
stack.append(num)
496. 下一个更大元素 I
输入: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 。
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = []
stack = []
# 存储内容 元素:下一个更大元素
mapping = {}
# 遍历nums2 ,创建单调递增栈
for num in nums2:
while stack and num > stack[-1]:
mapping[stack[-1]] = num
stack.pop()
stack.append(num)
for num in nums1:
if num in mapping:
res.append(mapping[num])
else:
res.append(-1)
return res
739. 每日温度
请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
n = len(temperatures)
res = [0]*n
# 栈用来存储更大元素的索引位置
stack = []
for i in range(n):
# 单调递增栈
while stack and temperatures[i] > temperatures[stack[-1]]:
index = stack.pop()
res[index] = i - index
stack.append(i)
return res
网友评论