栈
有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例:
输入:s = "()"
输出:true
输入:s = "()[]{}"
输出:true
输入:s = "(]"
输出:false
输入:s = "([)]"
输出:false
输入:s = "{[]}"
输出:true
提示:
1 <= s.length <= 104
s
仅由括号'()[]{}'
组成
思路:
遇到左括号就进栈,遇到右括号判断栈是否为空且栈的最后一位是否与当前的右括号匹配。当所有字符都匹配结束的时候,栈的状态应该是空栈。代码如下:
class Solution:
def isValid(self, s: str) -> bool:
stack = []
dic = {')':'(', ']':'[', '}':'{'}
for i in s:
if i in '([{':
stack.append(i)
elif stack and stack[-1] == dic[i]:
stack.pop()
else:
return False
return stack == []
逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。注意 两个整数之间的除法只保留整数部分。可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例:
输入:tokens = ["2","1","+","3","*"] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
输入:tokens = ["4","13","5","/","+"] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
输入:tokens = ["10","6","9","3","+","-11","","/","","17","+","5","+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
提示:
1 <= tokens.length <= 104
tokens[i] 是一个算符("+"、"-"、"*" 或 "/"),或是在范围 [-200, 200] 内的一个整数
思路:使用栈,详情思路见代码和代码注释
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = [] # 创建栈
for i in range(len(tokens)):
if tokens[i] not in '+-*/':
stack.append(tokens[i])
else:
tmp1 = stack.pop()
tmp2 = stack.pop()
res = eval(tmp2 + tokens[i] + tmp1) # 注意tmp2和tmp1的位置不要颠倒
stack.append(str(int(res))) # 这里int(res)主要是将小数部分省略
return int(stack[0]) #此时栈内只剩下一个数字
最小栈
设计一个支持
push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
push(x)
—— 将元素 x 推入栈中。
pop()
—— 删除栈顶的元素。
top()
—— 获取栈顶元素。
getMin()
—— 检索栈中的最小元素。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
pop
、top
和getMin
操作总是在 非空栈 上调用。
思路见代码,没什么好说的:
class MinStack:
def __init__(self):
self.stack = []
self.minstack = []
def push(self, val: int) -> None:
self.stack.append(val)
if not self.minstack or self.minstack[-1] >= val:
self.minstack.append(val)
def pop(self) -> None:
if self.stack.pop() == self.minstack[-1]:
self.minstack.pop()
def top(self) -> int:
if self.stack:
return self.stack[-1]
else:
return None
def getMin(self) -> int:
if self.minstack:
return self.minstack[-1]
else:
return None
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
基本计算器 II
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。
示例:
输入:s = "3+2*2"
输出:7
输入:s = " 3/2 "
输出:1
输入:s = " 3+5 / 2 "
输出:5
提示:
1 <= s.length <= 3 * 105
s
由整数和算符('+', '-', '*', '/')
组成,中间由一些空格隔开s
表示一个 有效表达式- 表达式中的所有整数都是非负整数,且在范围
[0, 231 - 1]
内- 题目数据保证答案是一个 32-bit 整数
思路:
class Solution:
def calculate(self, s: str) -> int:
n = len(s)
stack = []
preSign = '+'
num = 0
for i in range(n):
if s[i] != ' ' and s[i].isdigit():
num = num * 10 + ord(s[i]) - ord('0') # 数字可能不止一位
if i == n - 1 or s[i] in '+-*/':
if preSign == '+':
stack.append(num)
elif preSign == '-':
stack.append(-num)
elif preSign == '*':
stack.append(stack.pop() * num)
else:
stack.append(int(stack.pop() / num))
preSign = s[i]
num = 0
return sum(stack)