栈是⼀种受限的数据结构, 体现在只允许新的内容从⼀个⽅向插⼊或删除,这个⽅向我们叫栈顶,另⼀端⼀般称为栈底。除了栈顶的其他位置获取或操作内容都是不被允许的。栈最显著的特征就是 LIFO(Last In, First Out - 后进先出)
栈的常⽤操作与时间复杂度进栈
- push - 将元素放置到栈顶出栈
- pop - 将栈顶元素弹出取栈顶
- top - 得到栈顶元素的值判断是否为空栈
- isEmpty - 判断栈内是否有元素
复杂度分析:进栈 - O(1)出栈 - O(1)取栈顶 - O(1)判断是否为空栈 - O(1)
应⽤
栈是实现深度优先遍历的基础。除此之外,栈的应⽤还有很多,这⾥列举⼏个常⻅的。
- 函数调⽤栈
- 浏览器前进后退
- 匹配括号
- 单调栈⽤来寻找下⼀个更⼤(更⼩)元素
- 波兰表示法 和 逆波兰表示法
题目练习
150 逆波兰表达式求值
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +, -, *, and /. Each operand may be an integer or another expression.
Note that division between two integers should truncate toward zero.
It is guaranteed that the given RPN expression is always valid. That means the expression would always evaluate to a result, and there will not be any division by zero operation.
class Solution(object):
def evalRPN(self, tokens):
"""
:type tokens: List[str]
:rtype: int
"""
stack=[]
n=len(tokens)
for i in range(n):
if tokens[i] in ["+","-","*","/"]:
num2=stack.pop()
num1=stack.pop()
stack.append(int(self.calculate(int(num1),int(num2),tokens[i])))
else:
stack.append(tokens[i])
return stack.pop()
def calculate(self,nums1,nums2,op):
if op=='+':
return nums1+nums2
if op=='-':
return nums1-nums2
if op=='*':
return nums1*nums2
if op=='/':
return float(nums1)/nums2
1381 设计一个支持增量操作的栈
Design a stack which supports the following operations.
Implement the CustomStack class:
CustomStack(int maxSize) Initializes the object with maxSize which is the maximum number of elements in the stack or do nothing if the stack reached the maxSize.
void push(int x) Adds x to the top of the stack if the stack hasn’t reached the maxSize.
int pop() Pops and returns the top of stack or -1 if the stack is empty.
void inc(int k, int val) Increments the bottom k elements of the stack by val. If there are less than k elements in the stack, just increment all the elements in the stack.
class CustomStack(object):
def __init__(self, maxSize):
"""
:type maxSize: int
"""
self.stack=[]
self.maxsize=maxSize
def push(self, x):
"""
:type x: int
:rtype: None
"""
if len(self.stack)<self.maxsize:
self.stack.append(x)
def pop(self):
"""
:rtype: int
"""
if len(self.stack)>0:
top=self.stack[-1]
self.stack=self.stack[:-1]
return top
return -1
def increment(self, k, val):
"""
:type k: int
:type val: int
:rtype: None
"""
if len(self.stack)<=k:
self.stack=[i+val for i in self.stack]
else:
self.stack=[i+val for i in self.stack[:k]]+self.stack[k:]
394字符串解码
Given an encoded string, return its decoded string.
The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.
You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.
Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won’t be input like 3a or 2[4].
class Solution(object):
def decodeString(self, s):
"""
:type s: str
:rtype: str
"""
stk = []
for i in s:
try: # 使用try,可以方便地对当前字符是否是数字进行判断
num = int(i) # 这里的int(i)要单独占一行赋值语句
num = stk.pop()*10 + num if stk and isinstance(stk[-1], int) else num
stk.append(num)
except ValueError:
if i == ']':
tmp = i
while tmp[0] != '[': # 循环pop,直到遇到了左括号
tmp = stk.pop() + tmp
stk.append(stk.pop()*tmp[1:-1]) # 解码后,重新压入栈
else:
stk.append(i)
return ''.join(stk)
946 验证栈序列
Given two integer arrays pushed and popped each with distinct values, return true if this could have been the result of a sequence of push and pop operations on an initially empty stack, or false otherwise.
class Solution(object):
def validateStackSequences(self, pushed, popped):
"""
:type pushed: List[int]
:type popped: List[int]
:rtype: bool
"""
if not pushed:
return True
n=len(pushed)
stack=[]
j=0
for i in range(n):
stack.append(pushed[i])
while stack and stack[-1]==popped[j]:
stack.pop()
j+=1
return stack==[]