代码随想录算法训练营day13 | 150. 逆波兰表达式求值,239. 滑动窗口最大值,347.前 K 个高频元素

题目:

  • 150. 逆波兰表达式求值

    • 注意:The integer division should truncate toward zero, which means losing its fractional part. For example, 8.345 would be truncated to 8, and -2.7335 would be truncated to -2.

    • 对于truncate to zero的处理,python3和python2是有区别的!

      • int(a/b)在python3中是可以的,也可以用math.trunc(a/b),但在python2不可以。
    • 当需要container的时候,总是习惯直接用数组,缺少对于复杂度的考量,尤其是直接ac之后更不会继续思考。这里就是set更快!

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        
        stack = []
        
        for token in tokens:
            if token not in {'+', '-', '*', '/'}: # O(1) 查找
                stack.append(int(token))
                
            else:
                b = stack.pop()
                a = stack.pop()
                if token == '+':
                    stack.append(a+b)
                elif token == '-':
                    stack.append(a-b)
                elif token == '*':
                    stack.append(a*b)
                elif token == '/':
                    stack.append(int(a/b))
                    
        return stack[-1]
        

我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。

例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算法,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!

那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈里顺序处理,不需要考虑优先级了。也不用回退了, 所以后缀表达式对计算机来说是非常友好的。

  • 239. 滑动窗口最大值(hard)

    • 第一反应就是暴力解法,直接for循环,但是超时,O(n*k).

    • 考虑O(n)解法:通过视频讲解知道需要用单调递减队列(monotonically decreasing queue)

  1. 单调队列正式登场!| LeetCode:239. 滑动窗口最大值_哔哩哔哩_bilibili
  2. https://www.youtube.com/watch?v=DfljaUwZsOk
  • Q1: 为什么用队列而不是栈?
  • S:因为需要在beginning的位置进行增删操作,队列可以做到O(1).
  • Q2: 如下题解为什么使用deque而不是list来实现队列?
  • S:在day11 blog中有总结。
class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        
        # time O(n) + space O(k)
        
        ans = []
        queue = collections.deque() #this queue is to store index not value
        left = right = 0 #tell where the current window is
        
        while right < len(nums):
            #the below while loop is 
            #to make sure no smaller values(compare to nums[right]) in the queue, 
            #to pop smaller values
            while len(queue) != 0 and nums[queue[-1]] < nums[right]: 
                queue.pop() 
            queue.append(right)
            
            #remove left value from the window
            if left > queue[0]:
                queue.popleft()
            
            if right+1 >= k:
                ans.append(nums[queue[0]])
                left += 1
            
            right += 1
        
        return ans
  • 347.前 K 个高频元素(medium)

  • 题解1:

    • 第一反应是用dict,也就是hashmap,通过出现的次数来找出对应的前k个key(也就是nums里的值)

    • trick: Get key by value in dictionary

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        temp = {}
        for num in nums:
            if num not in temp:
                temp[num] = 1
            else:
                temp[num] += 1
        
        ans = []
        for i in range(k):
            max_key_by_value = list(temp.keys())[list(temp.values()).index(max(temp.values()))]
            temp[max_key_by_value] = 0
            ans.append(max_key_by_value)
        
        return ans

复杂度分析:(to be finished...)

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        
        count = {}
        freq = [[] for i in range(len(nums) + 1)]
        
        for num in nums:
            if num not in count:
                count[num] = 1
            else:
                count[num] += 1
        print(count)
        print(count.items())
        
        for num, c in count.items():
            freq[c].append(num)  
        print(freq)
        
        ans = []
        for i in range(len(freq)-1, 0, -1):
            for num in freq[i]:
                ans.append(num)
                if len(ans) == k:
                    return ans
  • 题解3: O(nlogk) + O(n)     (还没搞懂,弄懂了再贴到下面。。。)

总结:

  1. 单调队列的思路还需仔细琢磨

  2. 大小顶堆的概念不熟悉,需要单独学习一下。

代码随想录算法训练营43期 | Day 11——150. 逆波兰表达式求值239. 滑动窗口最大值(单调队列)、347. K 个高频元素(优先级队列) 单调队列:每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。此处的 “队列” 跟普通队列的一大不同就在于可以从队尾进行操作,STL 中有类似的数据结构 deque。 阅读详情

相关推荐

代码随想录算法训练营Day11 | 150.逆波兰表达式求值239.滑动窗口最大值347.K个高频元素

训练营第11天:150.逆波兰表达式求值239.滑动窗口最大值347.K个高频元素

jiabao0520的博客 1340

day11| 150. 逆波兰表达式求值 239. 滑动窗口最大值 347. K 个高频元素

/自定义数组//弹出元素时,比较当要弹出的数值是否等于队列出口的数值,如果相等则弹出//同时判断队列当是否为空if (!//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出//保证队列元素单调递减//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2while (!//队列队顶元素始终为最大值//存放结果元素的数组//自定义队列//先将k的元素放入队列i < k;

m0_65709641的博客 1103

代码随想录算法训练营Day12 | 150. 逆波兰表达式求值 | 239. 滑动窗口最大值 | 347. K 个高频元素

根据 逆波兰表示法,求表达式的值。有效的运算符包括 + , - , * , /。每个运算对象可以是整数,也可以是另一个逆波兰表达式。说明:整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

wonderlandlja的博客 1426

代码随想录训练营Day11 | 150. 逆波兰表达式求值 | 239. 滑动窗口最大值 | 347. K 个高频元素

这是使用单调队列的经典题目,此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。队列里的元素一定是要排序的,而且要最大值放在出队口,那么已经排序之后的队列 怎么能把窗口要移除的元素(这个元素可不一定是最大值)弹出呢。的滑动窗口从数组的最左侧移动到数组的最右侧。

m0_68965961的博客 1135

代码随想录训练营第42期 Day11打卡 LeetCode 150. 逆波兰表达式求值 239. 滑动窗口最大值 347. K 个高频元素

栈与队列

记得要努力变强 1344

代码随想录算法训练营day11(python版)|第五章 栈与队列part02| 150. 逆波兰表达式求值 239. 滑动窗口最大值347. K 个高频元素

150. 逆波兰表达式求值本题不难,但第一次做的话,会很难想到,所以先看视频,了解思路再去做题。

qq_43752779的博客 525

代码训练营 day11|LeetCode 150LeetCode 239LeetCode 347

今天主要学习了栈和队列的一系列操作,今天解锁了两个成就!太开心了,做出来困难题的时候!而且今天提做完了,相当于双休了!开心,明天奖励自己吃好的!加油,坚持打卡的第十天。

qq_44639909的博客 1075

【CV炼丹师勇闯力扣训练营 Day12:§5栈与队列P2】

代码随想录算法训练营第12天:§5栈与队列P2 ●150.逆波兰表达式求值239.滑动窗口最大值347. K 个高频元素

Tensorrrrrr的博客 805

代码随想录算法训练营day10~day13栈与队列No.232 225 20 1047 150 239 347

优先级队列和单调队列。

wangcles的博客 1086

代码随想录训练营第42期 打卡总结 - 刷题记录】

打卡总结

记得要努力变强 1605

Day_11_算法训练营第十一天 | LC_150. 逆波兰表达式求值 LC_239. 滑动窗口最大值 LC_ 347. K 个高频元素

代码Day_11_算法训练营第十一天 | LC_150. 逆波兰表达式求值 LC_239. 滑动窗口最大值 LC_ 347. K 个高频元素

2301_80354488的博客 260

力扣(合并区间)

给定一组可能重叠或相邻的整数区间,合并所有重叠或端点相接的区间,返回不重叠的最小区间列表。例如输入 [[1,3],[2,6],[8,10],[15,18]],输出 [[1,6],[8,10],[15,18]]。核心是先按左端点升序排序,再单次线性扫描完成合并,避免暴力两两比较。

weixin_52811458的博客 289

LeetCode 102. 二叉树的层序遍历|Python 解法详解

这道题的关键是:广度优先搜索天然按层访问。理解这一点后,再结合边界条件检查,代码就能保持清晰且稳定。

a1250467048的博客 159

leetcode 56合并区间

这道题你可以把它压缩成一个非常好记的思路:先排序,再逐个比较;能合并就扩右边界,不能合并就加入答案。具体来说,先用: 把所有区间按照左端点从小到大排序。排序之后,我们只需要拿“当区间”和 里最后一个已经合并好的区间比较。如果: 说明一个区间的右端点比当区间左端点还小,二者没有重叠: 所以直接: 如果不满足: 那就说明: 两个区间重叠,例如: 此时左端点不用动,只需要把右端点扩大: 所以整道题可以记成: 这道题容易忘的函数/语法 含义:对整个 排序。对于:

qq_63176310的博客 222

LeetCode //MySQL - 1204. Last Person to Fit in the Bus

This SQL query solves the problem of finding the last person who can board a bus without exceeding the 1000 kg weight limit. The solution involves: Calculating a running total of weights ordered by boarding turn using a window function Filtering to only in

Made in Code 349

LeetCode 1. 两数之和 | 从暴力枚举到哈希表最优解 + 空间换时间思想全复盘

文章摘要 题目要求在数组中找到两数之和等于目标值的下标。核心思路是优化查找效率: 暴力法:双重循环枚举所有数对,时间复杂度O(n²),效率低但易实现。 哈希表优化:利用哈希表O(1)查找特性,遍历时存储已访问元素,每次计算差值并查询,时间复杂度降至O(n)。关键细节是先查后存,避免自匹配。 代码实现:哈希表法通过一次遍历完成,空间换时间,边界处理需注意空数组和不足两元素的情况。 常见错误:内层循环起始点、哈希表键值设计、立即返回结果等易错点需警惕。 面试要点:优先选择哈希表解法,解释与暴力法的差异,强调时间

yc2284238579的博客 229

leetcode】153. 寻找旋转排序数组中的最小值js

本文介绍了在旋转排序数组中寻找最小值的二分查找算法。通过比较中间元素与数组末尾元素,可以确定最小值所在区间:若中间值大于末尾值,则最小值在右侧;否则在左侧或当位置。文章提供了两种实现方式,第一种通过样例总结返回nums[l],第二种采用更标准的二分写法,确保循环结束时left==right。两种方法时间复杂度均为O(logn),适用于解决LeetCode相关题目。关键点在于利用旋转数组的特性缩小搜索范围。

2402_83244812的博客 144

LeetCode //C - 1203. Sort Items by Groups Respecting Dependencies

This problem involves sorting items with group constraints and dependency relations. The key steps are: Assign unique groups to items with no group (-1) Build dependency graphs for both items and groups Perform topological sorting on both graphs If both so

Made in Code 366

LeetCode hot100——最大子数组和

给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。是数组中的一个连续部分。6连续子数组 [4,-1,2,1] 的和最大,为 6。nums = [1]123如果你已经实现复杂度为O(n)的解法,尝试使用更为精妙的求解。

weixin_42927227的博客 206
上一篇: 代码随想录算法训练营day11 | 232.用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047. 删除字符串中的所有相邻重复项
下一篇: 代码随想录算法训练营day14 | 二叉树理论基础,递归遍历,迭代遍历,统一迭代法
jzh013
博客等级 码龄4年 7粉丝 · 48原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值