代码随想录|栈与队列 704. 二分查找,27. 移除元素
python
一、20.有效的括号
1.核心代码
注意存栈的时候存另一半就可以了
# 方法一,仅使用栈,更省空间
class Solution:
def isValid(self, s: str) -> bool:
stack = []
for item in s:
if item == '(':
stack.append(')')
elif item == '[':
stack.append(']')
elif item == '{':
stack.append('}')
elif not stack or stack[-1] != item:
return False
else:
stack.pop()
return True if not stack else False
这行代码是有效括号检验算法的关键部分。这里的 elif 语句是在遍历输入字符串 s 每个字符的循环中。对于遇到的每个闭括号字符()、]、}),此 elif 分支会检查两个条件:
not stack:确保栈不为空。如果栈为空,但是循环遇到了一个闭括号,那意味着没有相对应的开括号,因此返回 False。
stack[-1] != item:检查栈顶元素是否与当前字符匹配。stack[-1] 是获取栈顶元素的方式。如果栈顶元素与当前遍历到的闭括号不匹配,则返回 False。这是因为每个开括号应该与其相对应的闭括号顺序匹配。例如,如果上一个开括号是 {,但当前字符是 ),则括号是不匹配的。
当你想在列表末尾添加元素时,你应该使用 append()。而当你想在集合中添加一个唯一元素时,你应该使用 add()。记住,尝试使用 add() 在列表中添加元素会导致 AttributeError,因为 list 对象没有 add() 方法。同样的,使用 append() 添加元素到集合会导致 AttributeError,因为 set 对象没有 append() 方法。
与c++的不同:取栈顶为stack[-1]
2.输入输出
def isValid(s):
stack=[]
for item in s:
if item =='(':
stack.append(')')
elif item=='{':
stack.append('}')
elif item=='[':
stack.append(']')
elif not stack or stack[-1]!=item:
return False
else:
stack.pop()
return not stack
if __name__=="__main__":
s=input()
ss=isValid(s)
print(ss)
二、逆波兰表达式求值
from operator import add, sub, mul
class Solution:
op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for token in tokens:
if token not in {'+', '-', '*', '/'}:
stack.append(int(token))
else:
op2 = stack.pop()
op1 = stack.pop()
stack.append(self.op_map[token](op1, op2)) # 第一个出来的在运算符后面
return stack.pop()
map的表达方式{‘+’:add,}
函数里有自变量的表达方式 lambda x,y:int(x/y)
s.replace(‘"’, ‘’)移除引号再可以化为整数
2、输入输出
这边输入输出碰到了很大的问题,“”双引号好像不太好去掉,而且必须在第一次输入的时候就去掉
from typing import List
from operator import add,sub,mul
class Solution:
op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
def evalRPN(self,tokens):
stack=[]
for s in tokens:
if s not in {'+','-','*','/'}:
stack.append(int(s))
else:
op2=stack.pop()
op1=stack.pop()
stack.append(self.op_map[s](op1,op2))
return stack.pop()
if __name__=="__main__":
tokens=input().strip().split()
solution=Solution()
n=solution.evalRPN(tokens)
print(n)
我想我是把输入输出想的太复杂了!如果想的简单一点就这样直接输出,然后去除一点空格就行了
注意除法的顺序就行了
三、239. 滑动窗口最大值
1、核心代码
from collections import deque
class MyQueue: #单调队列(从大到小
def __init__(self):
self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
#每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
#同时pop之前判断队列当前是否为空。
def pop(self, value):
if self.queue and value == self.queue[0]:
self.queue.popleft()#list.pop()时间复杂度为O(n),这里需要使用collections.deque()
#如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
#这样就保持了队列里的数值是单调从大到小的了。
def push(self, value):
while self.queue and value > self.queue[-1]:
self.queue.pop()
self.queue.append(value)
#查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
def front(self):
return self.queue[0]
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
que = MyQueue()
result = []
for i in range(k): #先将前k的元素放进队列
que.push(nums[i])
result.append(que.front()) #result 记录前k的元素的最大值
for i in range(k, len(nums)):
que.pop(nums[i - k]) #滑动窗口移除最前面元素
que.push(nums[i]) #滑动窗口前加入最后面的元素
result.append(que.front()) #记录对应的最大值
return result
刷到目前最长的python代码出现了!
右进左出
Python的collections.deque为了保持与列表的一致性和简化学习曲线,采用了append来向队尾添加元素和appendleft来向队首添加元素的方法名称。同样地,pop方法用于从队尾移除元素,而popleft用于从队首移除元素。
进口是后端pop,queue[-1],出口是前端queue[0] popleft
这道题不是很熟
2、输入输出
from collections import deque
class MyQueue:
def __init__(self):
self.queue=deque()
def pop(self,num):
if self.queue and num==self.queue[0]:
self.queue.popleft()
def push(self,num):
while self.queue and num>self.queue[-1]:
self.queue.pop()
self.queue.append(num)
def front(self):
return self.queue[0]
class Solution:
def maxSlidingWindow(self,nums,k):
que=MyQueue()
result=[]
n=len(nums)
for i in range(k):
que.push(nums[i])
result.append(que.front())
for i in range(k,n):
que.pop(nums[i-k])
que.push(nums[i])
result.append(que.front())
return result
if __name__=="__main__":
nums=list(map(int,input().strip().split(',')))
k=int(input())
solution=Solution()
result=solution.maxSlidingWindow(nums,k)
print(result)
总结
输入输出