准备知识

  • 优先级队列
    优先级队列本质上是一个,因为其接口函数使用的操作和队列非常类似,所以被称为priority_queue。创建一个优先级队列对象需要确认:1.数据类型;2.存放数据的容器;3.比较函数。在创建时参数缺省的情况下,默认使用vector作为容器以及大顶堆的存放方式。(堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。)下面看一下优先级队列在c++中的语法:

    priority_queue<int,vector<int>,function> que; //function为比较函数
    priority_queue<int> que; //大顶堆以vector为表现形式的complete binary tree(完全二叉树)
    que.push(i);
    que.pop();
    que.empty();
    que.size();
    

    优先级队列的pop操作是从堆顶开始的,也就是如果是大顶堆会pop最大值,小顶堆就会pop最小值。

239. 滑动窗口最大值

本题的标注难度为困难,思路不难,就是实现比较难想明白。本题卡哥给出的方法是自己实现一个单调队列,即滑动窗口时自己维护一个从大到小排序的队列,这样就可以在符合条件的时候直接使用队列top的元素作为答案输出,所以关键就是造一个符合题目要求的单调队列。
这里使用deque来实现单调队列,我觉得本题比较难的就是如何排出窗口内的最大值,但是在滑动过后不在窗口范围内的情况,所以需要考虑遍历时队列pushpop的顺序,以及pop时的判断。push的逻辑是不需要维护窗口内所有的元素,只需要维护可能为最大值的元素,如果当前元素大于队列中的元素,就先把队列中poppush,如果当前元素小于队尾的元素,直接push
直接使用代码解释:

class Solution {public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> ans;deque<int> que;//需要提前把第一个窗口的元素输入,因为这里不涉及滑动的逻辑。//同时可以解决nums.size()==k的特殊情况//这里也要遵循单调队列的push逻辑for (int i = 0 ; i < k ; i++) {while (!que.empty() && nums[i] > que.back()) {que.pop_back();}que.push_back(nums[i]);}//此时已经有第一个窗口的最大值了ans.push_back(que.front());for(int i = k; i < nums.size(); i++){//push逻辑while (!que.empty() && nums[i] > que.back()) {que.pop_back();}que.push_back(nums[i]);//判断队首元素是否以及不在窗口中if(que.front() == nums[i - k]){que.pop_front();}ans.push_back(que.front());}return ans;}
};

我认为本题比较关键的地方就是处理单调队列逻辑时的顺序,先push再判断是否需要pop最后输入答案。

347.前 K 个高频元素

本题需要前面介绍的优先级队列,对频率进行排序。思路还是很清晰的,首先使用一个map遍历数组,然后记录下每个元素出现的次数作为value。然后使用优先级队列对map进行遍历输出答案。优先级队列的内部实现时通过堆,本题应该使用小顶堆,因为其先进先出并且pop时弹出堆顶元素的特性决定了不应该使用大顶堆。
因为是对map遍历,所以优先级队列应该这样定义:

priority_queue<pair<int,int>, vector<pair<int, int>> , mycomparison> que;

mycomparison定义如下:

// 小顶堆class mycomparison {public:bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {return lhs.second > rhs.second;}};

其实这里我也不太懂,好像使用头文件#include <functional>中的lessgreater也可以实现大小顶堆。

可以看到priority_queue的数据类型为pair<int,int>,这是比较特殊的地方。
在对map进行遍历的时候,优先级队列中只维护k个元素,当队列的size大于k时,就pop
完整代码如下:

class Solution {public:// 小顶堆class mycomparison {public:bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {return lhs.second > rhs.second;}};vector<int> topKFrequent(vector<int>& nums, int k) {map<int,int> map;for(int i = 0; i < nums.size(); i++){map[nums[i]]++;}priority_queue<pair<int,int>, vector<pair<int, int>> , mycomparison> que;for(auto it = map.begin(); it != map.end(); it++){que.push(*it);if(que.size() > k) que.pop();}vector<int> ans(k);for(int i = k - 1; i >=0; i--){ans[i] = que.top().first;que.pop();}return ans;}
};

因为小顶堆的特性,所以最后输出答案从vector尾部开始,输入一个答案堆队列进行一次pop操作即可。

代码随想录第十三天 LeetCode 239、347(队列)相关推荐

  1. 代码随想录算法训练营第二天|leetcode 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

    leetcode 977.有序数组的平方 想到昨天写的双指针,十分刻意用了一下,感觉还是比较生疏,还得加强练习和思考,然后发现还需要排序,想到了vector的排序sort(),但是觉得直接用不好,也忘 ...

  2. 代码随想录算法训练营第四十三天 | 填满背包有几种方法、背包有两个维度

    1049.最后一块石头的重量II 文档讲解:代码随想录 (programmercarl.com) 视频讲解:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II ...

  3. Leetcode 704.二分查找 27.移除元素 代码随想录day1

    本系列目的在于跟练代码随想录,以及记录自己在数据结构与算法方面的一些学习 704.二分查找 其实之前自己在随便刷题的时候看过这道题目,就是一个纯新手的大状态,第一次听到二分查找这样的东西,然后跟着题解 ...

  4. 代码随想录算法训练营第十三天|102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

    链接:代码随想录 文章目录 102.二叉树的层序遍历 226.翻转二叉树 101.对称二叉树 解题方法 题目思路 示例代码 总结 解题思路 1.102.二叉树的层次遍历 解题思路 递归法,创立二维数组 ...

  5. 代码随想录(day04)-LeetCode:24、19、面试题02.07、142

    代码随想录:dayo4 1. [24]两两交换链表中的节点 虚拟头结点实现 递归实现 2.[19]**删除链表的倒数第N个节点** 双指针算法 3. 面试题[02.07]:链表相交 4.[142]环形 ...

  6. Leetcode刷题笔记(代码随想录)

    1 数组 1.1 二分查找 第一种写法:我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] .区间的定义这就决定了二分法的代码应该如何写,因为定义target在[le ...

  7. 代码随想录刷题|LeetCode 332.重新安排行程 51. N皇后 37. 解数独

    目录 332.重新安排行程 思路 重新安排行程 51. N皇后 思路 N皇后 37. 解数独 思路 解数独         这三道题目都是困难题目,都是根据代码随想录的思路总结书写,慢慢理解,慢慢熟练 ...

  8. 代码随想录一刷个人记录

    代码随想录一刷个人记录 2022/7/14(leetcode) 2022/7/15(leetcode) 2022/7/17[字符串] 2022/7/18[字符串] 2022/7/20[双指针] 202 ...

  9. 《labuladong的算法小超》A和《代码随想录》B阅读笔记(2)

    第9天 63.不同路径 你看,今天就涉及到带有路障的机器人运动问题了.先上代码再解析 class Solution:def uniquePathsWithObstacles(self, obstacl ...

  10. 代码随想录算法训练营Day12 栈与队列

    #代码随想录算法训练营 代码随想录算法训练营Day12 栈与队列| 239. 滑动窗口最大值 347.前 K 个高频元素 总结 239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑 ...

最新文章

  1. 企业级 SpringBoot 教程 (十七)上传文件
  2. 求两个集合是否有交集 c语言_高中数学:集合与函数概念知识点总结
  3. C和C++中static的用法及友元
  4. 谷歌浏览器修复一键修复_谷歌发布Chrome 86.0.4240.198 修复两个零日漏洞 - Google Chrome 谷歌浏览器...
  5. H5之audio标签放音兼容所有浏览器方法
  6. Gitlab 项目上传
  7. C语言,谁都能看得懂的归并排序
  8. Spark 某两个节点数据分析速度慢 - hbase数据删除(分裂) 元信息未删除导致 There is an overlap in the region chain.
  9. 编写Java程序 堆栈的接口_java - 错误:调用实现接口的通用方法时,java.lang.AbstractMethodError - 堆栈内存溢出...
  10. linux后台运行python程序 nohup不挂断
  11. webdriver---API---(java版) 高级应用
  12. f-stack nginx 多进程模式启动 main_loop 流程分析
  13. MYSQL基础:mysql客户端工具
  14. vue导出js中的函数_js中的函数
  15. 怎样快速的将WPS文件转换为word格式
  16. vue下载pdf为空问题解决
  17. 虚拟机设置共享文件夹不显示
  18. 为什么IPv6显示无网络访问权限
  19. 揭开程序员装 13 行为的面具
  20. w ndows远程自动退出登陆,远程桌面连接Wndows 常见故障解决方法.doc

热门文章

  1. 云风专访|近40年码龄,从通宵写代码到三思而后行
  2. ubuntu系统Firefox浏览器B站视频无法播放
  3. 区块链骗局盘点,有人暴富,有人破产
  4. python求矩阵的秩_python – 计算所有子矩阵有多少个矩阵具有满秩
  5. WatchGuard 防火墙封 Msn qq icq
  6. 修改无线网密码后服务器拒绝访问,路由器重设密码怎么上不了网
  7. 【RTD】二分法查找和分段线性插值算法在RTD中应用
  8. MULTIPLE SPRING BOOT RUN CONFIGURATIONS WERE DETECTED. RUN DASHBOARD ALLOWS TO【已解决】
  9. 离职创业三年后,我来谈谈我的感受
  10. UVa 10827 - Maximum sum on a torus