leetcode 第十一天 2024.3.22

本文介绍了如何使用栈和队列数据结构解决LeetCode中的三个问题:删除字符串中的相邻重复项,逆波兰表达式求值,以及滑动窗口最大值。作者提到使用deque而非list操作栈以提高效率,以及自定义单调队列解决滑动窗口问题的难点。
摘要由CSDN通过智能技术生成

1. 删除字符串中的所有相邻重复项:
 题目链接: 1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
应用条件:栈

难点:

这道题要想到可以用栈来解决问题。如果想到的话很简单。可以用list实现,也可以用deque来实现。

个人错误:

对于用一个list实现栈的操作还有些陌生,但用deque做出了这道题,用时似乎比用list更长一些。

思路:

如下

class Solution:
    def removeDuplicates(self, s: str) -> str:
        res = list()
        ans = ''
        for item in s:
            if res and res[-1] == item:
                res.pop()
            else:
                res.append(item)
        for j in res:
            ans = ans+j
        
        return ans

2. 逆波兰表达式求值:
 题目链接: 1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)150. 逆波兰表达式求值 - 力扣(LeetCode)1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
应用条件:栈

难点:

这道题要想到可以用栈来解决问题。如果想到的话很简单。可以用list实现,也可以用deque来实现。

个人错误:

对于用一个list实现栈的操作还有些陌生,但用deque做出了这道题,用时似乎比用list更长一些。

思路:

如下

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        r = deque()
        for i in tokens:
            if i == '+':

                a = r.popleft()
                b = r.popleft()
                res = int(a) + int(b) 

                r.appendleft(res)
            elif i == '-':
                a = r.popleft()
                b = r.popleft()
                res = int(b) - int(a)  
                r.appendleft(res)
            elif i == '/':
                a = r.popleft()
                b = r.popleft()
                res = int(b) / int(a) 
                r.appendleft(res)
            elif i == '*':

                a = r.popleft()
                b = r.popleft()
                res = int(b) * int(a)

                r.appendleft(res) 
            else:
                r.appendleft(i)
        return int(r[0])     

3. 滑动窗口最大值:
 题目链接: 239. 滑动窗口最大值 - 力扣(LeetCode)
应用条件:栈

难点:

这道题要想到可以用栈来解决问题。但需要自己定义一个单调队列类。我尝试遍历整个数组再遍历每个滑动窗口,结果是超时的。所以需要自己去定义单调队列,自己定义队列中的pop,push,以及查询方法我命名为lo。通过自己定义的这个队列,我们直接从k处遍历nums到结尾,运行时间是n-k。这样就不会超时。在定义队列时候,问题的难点是,pop和push方法,有两点值得注意,首先,要想到我们每次加入新的元素时,我们需要将单调队列中前面所有比这个新元素小的数都pop出去,换句话说,当新元素X进入队列时,我们将队列中所有<小于X的数都移除,这样我们就可以保证我们的队列中第一个数永远都是最大值,这也方便了我们的查询方法,我们只需要返回队列第一个元素就可以了。对于队列的pop方法,我们需要判断此时要移除的元素是不是我们队列中的最大值(队列中的第一个元素)如果是,我们将第一个元素移除,如果不是,我们可以不用管,因为我们在添加此时最大值元素的同时已经将前面所有小的元素都移除了。

个人错误:

想不到自己定义队列的操作,同时对自己定义class也不熟悉,实践操作太少。

思路:

如下

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        que = Myque()
        res = []
        for i in range(k):
            que.push(nums[i])
        res.append(que.lo())
        for i in range(k,len(nums)):
            que.pop(nums[i-k])
            que.push(nums[i])
            res.append(que.lo())
        return res


class Myque:
    def __init__(self):
        self.queue = deque()
    def pop(self, value):
        if self.queue and self.queue[0] == value:
            self.queue.popleft()
    def push(self, value):
        while self.queue and value> self.queue[-1]:
            self.queue.pop()
        self.queue.append(value)
    def lo(self):
        return self.queue[0]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值