代码随想录算法训练营第十一天| 150. 逆波兰表达式求值 239. 滑动窗口最大值

150. 逆波兰表达式求值

力扣150. 逆波兰表达式求值

代码随想录题解

这道题之前学过,但是忽略了6整除-132等于0这种极端情况,看到题解才知道如何处理除法,代码如下:

class Solution(object):
    def evalRPN(self, tokens):
        stack = []
        for i in tokens:
            if i in ['+', '-', '*', '/']:
                # 如果遇到操作符,则从栈中取出两个元素进行相应的计算
                right_operand = stack.pop()
                left_operand = stack.pop()
                if i == '+':
                    newNum = left_operand + right_operand
                elif i == '-':
                    newNum = left_operand - right_operand
                elif i == '*':
                    newNum = left_operand * right_operand
                elif i == '/':
                    # 对于除法,需要特别注意结果应向下取整 6整除-132 == 0
                    newNum = int(left_operand / right_operand) if left_operand * right_operand > 0 else -(abs(left_operand) // abs(right_operand)) 
                    # 使用 int() 来向下取整
                stack.append(newNum)
            else:
                # 如果不是操作符,则直接将字符串转换为整数并压入栈
                stack.append(int(i))
        return stack.pop()

239. 滑动窗口最大值

力扣239

读完题目觉得没那么难,但是提交代码的时候就嘻嘻了

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        left = 0
        right = k
        res = []
        while right <= len(nums):
            que = nums[left:right]
            res.append(max(que))
            left += 1
            right += 1
        return res

直接超时,我的代码时间复杂度为 O(n * k),还是老老实实学吧。这道题的思路是创建一个队列,这个队列是单调递减的,保持最大的数在队头,所以遍历数组的每个元素的时候,只需要获取对头的元素即可。这样就能输出最大值。具体的Push和Pop函数如何设计见代码吧,我看了好久也不明白为啥这样设计的,这是怎么想到的,先用代码随想录题解的代码记一下了:

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

347.前 K 个高频元素

如果直接写写不好,还是得学。

这里用到优先级队列会方便一些,可以理解为只维护长度为K的优先级队列,这样时间复杂度就是O(nlogk)低于快排的时间复杂度。优先级队列是通过堆来实现的,用的还不是很熟练,目前可以先理解为自动排序的字典,只不过显示为数组(key:value创建,但是print的时候只显示value)。代码如下,细节都在备注里:

import heapq#用堆创建优先级队列来解
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        mapNum = {}
        for i in nums:
            if i not in mapNum:
                mapNum[int(i)] = 1
            else:
                mapNum[int(i)] += 1
        
        priQ = []#小顶堆
        for num, freq in mapNum.items():
            heapq.heappush(priQ, (freq, num))
            if len(priQ) > k:
                heapq.heappop(priQ)
        result = [0] * k#创建好数组,便于倒序遍历,因为heapq的heappop方法只能弹出最小数字,要把较小出现频率的放在靠后的位置
        for i in range(k-1, -1 ,-1):#倒序遍历,从k-1一直到0
            result[i] = heapq.heappop(priQ)[1]#这里的方括号里的索引 1 表示我们想要获取元组中的第二个元素,
            #即数字本身。如果我们使用索引 0,我们将得到频率而不是数字
        return result

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值