力扣刷题|“队列“标签小节 (简单1 中等6 困难4) 思路+代码+细致注释~

“队列”标签下的题目,共计12题:

  • 简单1题
  • 中等7题,其中1856最优解是单调栈,没做;1673最优解也是单调栈,先写了一个脑筋急转弯的方法~
  • 困难4题,1825最优解是堆吧,先写了个队列的解算法,好慢啊…

队列就是先进先出的数组,有的题目可以使用多种数据结构实现,纯数组,有序数组,队列,双端队列,循环队列,栈,堆等等~

数据结构+算法的最优组合,才可以做出最优解~~ 不合适就不要勉强~

933. 最近的请求次数 (队列 数组 deque 细致注释~) &求解惑~~

虽然是一道简单题,可是,问题很多…求解惑…不同方法的时间复杂度让人很意外

  • 首先,直接暴力求解。执行用时: 292 ms
  • 然后,想要用时间换空间,每次从数组中pop出超时的元素,以为使用了pop,时间复杂度会增加,空间复杂度会好一点,结果…268 ms
  • 发现小伙伴都是用(while t - self.times[0] > 3000:),而我还在使用(while self.times[-1] - self.times[0] > 3000:),直接取t的值应该快一点吧,改成了t,结果是…352 ms…
  • 最后,使用了deque,据说以近似O(1)的效率在两端插入或删除元素,结果是292 ms

看测试结果,时间复杂度最好的是方法2,直接用数组pop.…使用deque空间复杂度好一点。综合起来,还是数组pop好一点。为什么?..

199. 二叉树的右视图 (队列 数组 广度优先搜索 BFS | 细致注释~)

方法1:广度优先搜索,使用词典+双向队列记录每层最后一个节点。 52ms/ 14.8MB

  • 建立词典(键为节点深度,值为节点的值)
  • 使用双向队列,进行广度优先搜索,将每层最后一个节点录入词典
  • 最后,根据节点深度,依次输出相应的值

方法2:直接使用数组/队列按层遍历,同时记录每层最后一个元素,最后输出。 36ms/90%; 14.8MB/64%

  • 按层遍历,每次仅存储当前行最后一个节点的值(res.append(nodes[-1].val))
  • 最后,直接输出数组

621. 任务调度器(队列 数组 Counter | 细致注释~)

方法1:分两种情况 68 ms/97% 16.1 MB/87%

  • 任务总类和数量充足,无需等待,直接返回len(tasks)
  • 任务总类和数量不足,需加入等待时间
  • 例如,任务列表为aaabbbcccddef, 对于出现频次最高的几个任务a/b/c,每轮处理一个任务a/b/c,余下的等待时间用于处理其余数量较少的任务。如,第一轮处理完abc后可以处理dd,第二轮处理完abc后处理ef,第三轮处理完abc结束

方法2:使用python内置函数精简了代码,提升了时空复杂度…80 m/79%s 16.2 MB/70%

622. 设计循环队列 (队列 数组 设计 | 细致注释~)

方法1:

  • 思路:数组+双指针。按照题意书写代码
  • 时空消耗:92 ms/23% 15.5 MB/65%

方法2:

  • 思路:使用纯数组实现,果然,还是快
  • 时空消耗:68 ms/99% 15.6 MB/24%

641. 设计循环双端队列(队列 数组 设计 | 细致注释~)

方法1:

  • 思路:数组+双指针。按照题意书写代码
  • 时空消耗:84 ms/49% 15.3 MB/96%

方法2:

  • 思路:使用纯数组实现,果然,还是快
  • 时空消耗:76 ms/89% 15.6 MB/53%

面试题 17.09. 第 k 个数(队列 堆 | 细致注释~)

解法1:

  • 思路:使用队列,依次加入一个最小数(从之前队列中"被标记的三个元素"分别乘以3/5/7的值中选取最小值)。
  • 用时:32 ms/98%;内存:14.6 MB/96%

解法2

  • 思路:使用最小堆,确保每次取出的都是最小的数字。压入时比较随意,因为堆会自动排序。
  • 用时:56 ms/10% 14.9 MB/29% 很慢…

1673. 找出最具竞争力的子序列 (数组 队列 细致注释~)

这道题的最优解是使用“栈”,我本周选择的主题是“队列”,这道多标签的题也有队列的标签,就恰好做到了。“栈”的解法等做“栈”的标签时再考虑,这里,就作为一个脑筋急转弯的题目啦~ 用时很久…不过代码简单~~

剑指 Offer 59 - I. 滑动窗口的最大值(队列 数组 滑窗 | 细致注释~)

果然,纯数组直接做又比deque快… 64 ms/87% 18.1 MB/42%
在这里插入图片描述

1825. 求出 MK 平均值(堆 队列 数组 设计| 细致注释~)

这道题的最优解是使用"堆"吧,在刷"队列"标签时遇到,先做队列和数组的解,等做到"堆"标签时再来更新。

解法1: 9528 ms 44.1 MB,内存消耗击败100%的小伙伴,执行用时,在图上找不到…

  • 维护两个数组,一个原数组,一个有序数组
  • 原数组用于记录元素的顺序
  • 有序数组使用二分确保实时有序,并维护元素总和
  • 计算平均值前比较m和3k,选择计算量比较少来算

解法2: 调用内置的有序列表 7700 ms 45.2 MB

862. 和至少为 K 的最短子数组(队列 数组 | 细致注释~)

方法1 使用双端队列

  • 执行用时: 280 ms/91% 内存消耗: 19.6 MB/100%
    思路:
  • 理解题意!“返回A的最短的非空连续子数组的长度,该子数组的和至少为K。”。和只要和大于k即可,如[2,-1,2,3],K=1,答案是1(第一个数字2就可以满足),不是2(前两个元素2-1恰好等于1)…
  • 根据题意,忽略负值元素
  • 原地更新数组A,用于存储前缀和
  • 使用双端队列存储前缀和数组中元素的下标
  • 计算当前元素num与前缀和数组中最后一个元素A[index_list[0]]的差,一旦满足“和至少为K”的要求,就计算两个索引之间的差,并更新最优解

方法2 直接使用数组 没想到这次数组比双端队列慢…

  • 执行用时: 504 ms/81% 内存消耗: 19.7 MB/100%

363. 矩形区域不超过 K 的最大数值和 (队列 数组 二分 动态规划 | 细致注释~)

时空消耗:1488 ms/74% 15 MB/99%

思路:先固定左,右边界,再累计每行,然后按列累计,比较。

  • 按照题意需遍历二维数组中各个矩形框范围,滚动累计求和,差值和k比较,例A = [[1,0,1],[0,-2,3]], K = 2
  • 使用left, right作为两侧的边界,不断右移right,然后右移left
  • 滚动记录left和right之间每行元素的动态累计和(前缀和)
  • 计算sums的值, 当left, right都为0时,就是第一列的值,[1,0]
  • 当left为0, right为1时,就是前两列的累计和,[1,-2]
  • 随着right逐渐右移,sums中就依次记录了每行元素的累计和
  • 当right右移到边界后,开启下一轮left的循环。left += 1, right in range(left, col)
  • 再使用cur存放按列累计的sums(经过几层循环遍历,cur就存储了所有矩形的和)
  • 借助二分查找,计算当前小于k的最大差值(当前累计和cur与之前存在的某个累计和之间的差),参见注释
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值