了解单调栈先要了解栈。栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。所以它是一种后入先出(LIFO)的数据结构。
而单调栈是一种单调递增或单调递减的栈,跟单调队列差不多,但是只用到它的一端。
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]
1 <= temperatures.length <= 105
30 <= temperatures[i] <= 100
class DailyTemperature(object):
def dailyTemperatures(self, temperatures: list) -> list:
"""
:type temperatures: List[int]
:rtype: List[int]
"""
length = len(temperatures)
if length <= 0:
return []
if length == 1:
return [0]
# res用来存放第i天的下一个更高温度出现在几天后
res = [0] * length
# 定义一个单调栈
stack = []
for index in range(length):
current = temperatures[index]
# 栈不为空 且 当前温度大于栈顶元素
while stack and current > temperatures[stack[-1]]:
# 出栈
pre_index = stack.pop()
# 当前索引和出栈索引差即为出栈索引结果
res[pre_index] = index - pre_index
stack.append(index)
return res
if __name__ == "__main__":
demo = DailyTemperature()
temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
print(demo.dailyTemperatures(temperatures))
该题目是把索引和温度绑定一起入栈出栈,按照温度降序入栈,出栈之差即距离当天第几天升温。
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
注意:
你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
提示:
1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空
import collections
class MyStack(object):
def __init__(self):
# deque是双端队列,queue是单端队列
# deque1用于存储栈内元素
self.deque1 = collections.deque()
# deque2用于存储临时元素
self.deque2 = collections.deque()
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.deque2.append(x)
while self.deque1:
# 队列具有先入先出FIFO特性:
# popleft()方法用于从队列的左侧(开头)删除元素,并返回被删除的元素
# pop()方法用于从队列的右侧(末尾)删除元素,并返回被删除的元素
self.deque2.append(self.deque1.popleft())
self.deque1, self.deque2 = self.deque2, self.deque1
def pop(self):
"""
:rtype: int
"""
return self.deque1.popleft()
def top(self):
"""
:rtype: int
"""
return self.deque1[0]
def empty(self):
"""
:rtype: bool
"""
return not self.deque1
if __name__ == "__main__":
stack = MyStack()
stack.push(1)
stack.push(2)
print(stack.top())
print(stack.top())
print(stack.empty())