232.用栈实现队列
225. 用队列实现栈
这两道题属于练手比较简单,回顾一下,有如下思考。
1.栈实现队列,我们需要两个栈来模拟一个队列,而用队列模拟栈只需要一个队列。
2.在python中,我们用deque()双端队列去模拟栈
3.在写成员函数时,建议先写最后一个判空函数,这样可以为前边所用。
20. 有效的括号
这题是最经典栈的应用,解题关键在于,对三种情况的分类和充分讨论,写在注释里了:
class Solution(object):
def isValid(self, s):
stack = []
for item in s:
if item == '(':
stack.append(')')
elif item =='[':
stack.append(']')
elif item =='{':
stack.append('}')
elif stack:#左右不匹配的情况
ans =stack.pop()
if item != ans:
return False
else:#包括了右括号多的情况
return False
if stack:#左括号多
return False
即:
1.左括号多于右括号,遍历字符串出循环后,栈不为空
2.右括号多于左括号,在循环遍历中,栈提前空了
3.右括号不等于左括号
1047. 删除字符串中的所有相邻重复项
这个题目是一个字符串形式的,一维的,对对碰消除游戏。
class Solution(object):
def removeDuplicates(self, s):
stack =[]
for item in s:
if stack and item == stack[-1]:
stack.pop()
else:
stack.append(item)
return "".join(stack)
150. 逆波兰表达式求值
回到学408的青涩时光,这就是后缀表达式的运算,第一次学的时候觉得很难,但是难得是自己手动把中缀转成后缀,这里只是,给你一个合法的后缀让你算一下数,所以只是简单的栈得应用,轻松过掉好吗?
注意的点:这里的除法向零取整,意思是对于结果为负数得除法,要取大的,反之对于正数结果取小的。
from operator import add, sub, mul
def div(x,y):
if x*y>0:
return x//y
else:
return -(abs(x)//abs(y))
class Solution(object):
op ={'+':add,'-':sub,'*':mul,'/':div}
def evalRPN(self, tokens):
stack=[]
for token in tokens:
if token in {'+','-','*','/'}:
op2=stack.pop()
op1=stack.pop()
result = self.op[token](op1,op2)
stack.append(result)
else:
stack.append(int(token))
return stack.pop()
239. 滑动窗口最大值
1.pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作。
2.push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止。
from collections import deque
class Solution(object):
def maxSlidingWindow(self, nums, k):
quene=deque()
result=[]
quene.append(0)
for i in range(1,k):
while quene and nums[i]>nums[quene[-1]]:
quene.pop()
quene.append(i)
result.append(nums[quene[0]])
for i in range(k,len(nums)):
if len(quene)>=k or quene[0] <= i-k:
quene.popleft()
while quene and nums[i]>nums[quene[-1]]:
quene.pop()
quene.append(i)
result.append(nums[quene[0]])
return result
这题我是按照自己的思路写的,靠豆包改的。
值得注意的是:
1.队列里最好是存索引,而不是数值,这样在维持这个单调队列长度时会比较轻松,避免了相同值带来的可能的谬误。
2.我认为这里边还有一个误导在,所谓的单调队列,并不是只能先进先出,从代码中也可以看出这是一个deque,而单调队列,强调的是,在由deque到result的过程中是一个队列的感觉,而在维持这个单调队列时,其实是一个栈。
347.前 K 个高频元素
本题使用了堆的概念,由于学过408的缘故,我第一反应总是把它想成二叉树,其实用一维数组来描述堆也是可以的。由于是求前k个高频元素,只需要维持一个k大小的小顶堆就可以了,越小越会出局,最后剩的就是k个最大的。
import heapq
class Solution(object):
def topKFrequent(self, nums, k):
ma={}
for num in nums :
ma[num]=ma.get(num,0)+1
heap1=[]
for key,freq in ma.items():
heapq.heappush(heap1,(freq,key))
if len(heap1)>k:
heapq.heappop(heap1)
result=[0]*k
for i in range(k-1,-1,-1):
result[i]=heapq.heappop(heap1)[1]
return result
值得注意的点:
1.对于heappush()的第二个参数,构建小顶堆的过程,先比较freq的大小,相同则比第二个,所以要这么写,下边倒数第二行[1]也来自于这个。
2.result一定要[0]*k,要不然下边倒序赋值一定会越界。