一、單調(diào)棧
一種特殊的棧,在棧的「先進(jìn)后出」規(guī)則基礎(chǔ)上,要求「從 棧頂 到 棧底 的元素是單調(diào)遞增(或者單調(diào)遞減)」。其中滿足從棧頂?shù)綏5椎脑厥菃握{(diào)遞增的棧,叫做「單調(diào)遞增?!?。滿足從棧頂?shù)綏5椎脑厥菃握{(diào)遞減的棧,叫做「單調(diào)遞減?!?。
單調(diào)遞增棧:只有比棧頂元素小的元素才能直接進(jìn)棧,否則需要先將棧中比當(dāng)前元素小的元素出棧,再將當(dāng)前元素出棧。結(jié)果:從棧頂?shù)綏5椎脑刂凳?strong>單調(diào)遞增的。
單調(diào)自減棧:只有比棧頂元素大的元素才能直接進(jìn)棧,否則需要先將棧中比當(dāng)前元素大的元素出棧,再將當(dāng)前元素入棧。
二、單調(diào)棧適用場景
單調(diào)棧可以在時間復(fù)雜度為O(n)的情況下,求解出某個元素左邊或者右邊第一個比它大或者小的元素。
口訣:
查找 「比當(dāng)前元素大的元素」 就用 單調(diào)遞增棧,查找「比當(dāng)前元素小的元素」就用 單調(diào)遞減棧。
從 「左側(cè)」 查找就看 「插入棧」 時的棧頂元素,從 「右側(cè)」 查找就看 「彈出棧」 時即將插入的元素。
二、代碼模板
- 單調(diào)遞增棧模板(棧底到棧頂單調(diào)遞增)
def IncreasingStack(nums):
stack = []
for num in nums:
# 當(dāng)前值大于棧頂元素,將棧頂元素彈出
while stack and num >= stack[-1]:
stack.pop()
stack.append(num)
- 單調(diào)遞減模板(棧底到棧頂單調(diào)遞減)
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 ,用加粗斜體標(biāo)識,nums2 = [1,2,3,4]。下一個更大元素是 3 。
- 4 ,用加粗斜體標(biāo)識,nums2 = [1,2,3,4]。不存在下一個更大元素,所以答案是 -1 。
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = []
stack = []
# 存儲內(nèi)容 元素:下一個更大元素
mapping = {}
# 遍歷nums2 ,創(chuàng)建單調(diào)遞增棧
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. 每日溫度
請根據(jù)每日 氣溫 列表 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):
# 單調(diào)遞增棧
while stack and temperatures[i] > temperatures[stack[-1]]:
index = stack.pop()
res[index] = i - index
stack.append(i)
return res