面对恐惧day10+day11(栈和队列)

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,要不然下边倒序赋值一定会越界。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值