day12 | 239. 滑动窗口最大值、347.前 K 个高频元素、

news/2024/11/23 5:44:36/

目录:

链接

题目链接:

https://leetcode.cn/problems/sliding-window-maximum/

https://leetcode.cn/problems/top-k-frequent-elements/

解题及思路学习

239. 滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k **的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 。

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  731 [3  -1  -3] 5  3  6  731  3 [-1  -3  5] 3  6  7 51  3  -1 [-3  5  3] 6  751  3  -1  -3 [5  3  6] 761  3  -1  -3  5 [3  6  7]7

思考:这题考察队列。将滑动窗口想象成一个队列从左到右滑动,可以将最大值固定存放在队列尾位置,也可以用一个变量存放。由于没写过队列相关题,直接看视频(原思考错误,是要输出每个窗口k的最大值)

随想录:自己实现一个队列,将最大值放在出队口。其实队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。

设计单调队列的时候,pop,和push操作要保持如下规则:

  1. pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
  2. push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

代码:

class Solution {
private:class MyQueue { //单调队列(从大到小)public:deque<int> que; // 使用deque来实现单调队列// 每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。// 同时pop之前判断队列当前是否为空。void pop(int value) {if (!que.empty() && value == que.front()) {que.pop_front();}}// 如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。// 这样就保持了队列里的数值是单调从大到小的了。void push(int value) {while (!que.empty() && value > que.back()) {que.pop_back();}que.push_back(value);}// 查询当前队列里的最大值 直接返回队列前端也就是front就可以了。int front() {return que.front();}};
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> result;for (int i = 0; i < k; i++) { // 先将前k的元素放进队列que.push(nums[i]);}result.push_back(que.front()); // result 记录前k的元素的最大值for (int i = k; i < nums.size(); i++) {que.pop(nums[i - k]); // 滑动窗口移除最前面元素que.push(nums[i]); // 滑动窗口前加入最后面的元素result.push_back(que.front()); // 记录对应的最大值}return result;}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(k)

整体思路是自定义了一个队列,然后将其设置为单调递增。每次弹出的时候,弹出最前面的最大值。

压入的时候,如果压入的值比后面的值要大,则一直弹出后面的值,再压入值。每一次滑动的时候,将最大值存入result。

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入:nums = [1,1,1,2,2,3], k = 2
输出:[1,2]

思考:可以用哈希表里面的map,记录每个数字出现的次数。之后再排个序。

随想录:

这道题目主要涉及到如下三块内容:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

统计元素出现的频率,可以用map统计。对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列(其实就是一个披着队列外衣的堆)堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。

为什么不用快排呢, 使用快排要将map转换为vector的结构,然后对整个数组进行排序, 而这种场景下,我们其实只需要维护k个有序的序列就可以了,所以使用优先级队列是最优的。

用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q72udXlt-1686148276970)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/162c480c-854b-4663-96c1-fedacdceed55/Untitled.png)]

代码

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) {// 要统计元素出现频率unordered_map<int, int> map; // map<nums[i],对应出现的次数>for (int i = 0; i < nums.size(); i++) {map[nums[i]]++;}// 对频率排序// 定义一个小顶堆,大小为kpriority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;// 用固定大小为k的小顶堆,扫面所有频率的数值for (unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++) {pri_que.push(*it);if (pri_que.size() > k) { // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为kpri_que.pop();}}// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组vector<int> result(k);for (int i = k - 1; i >= 0; i--) {result[i] = pri_que.top().first;pri_que.pop();}return result;}
};

这道题考察数据结构比较多。

****c++的priority_queue各种使用方法:****https://blog.csdn.net/sexyluna/article/details/125901499

困难及收获

困难

数据结构和C++某些用法不太熟

今日收获

栈和队列的更进一步用法。


http://www.ppmy.cn/news/266082.html

相关文章

串口助手(布局,图标,串口号,隐藏界面,显示实时时间)

文章目录 前言一、串口助手布局二、设置软件的标题&#xff0c;图标三、显示可用串口号四、隐藏&#xff0c;显示面板五、显示实时时间总结 前言 从这篇文章开始 教大家自己制作一个串口助手软件&#xff0c;并实现基本的功能。学做一个 串口助手可以一边回顾复习 QT 的相关知…

Android处理器

全文框架按阵营分为&#xff1a; Ⅰ、ARMv4架构阵营&#xff0c;代表核心&#xff1a; ARM9核心 Ⅱ、ARMv6架构阵营&#xff0c;代表核心&#xff1a; ARM11核心 Ⅲ、ARMv7架构阵营&#xff0c;代表核心&#xff1a; ①高通Scorpion核心 ②Cortex A8核心 …

揭开芯面纱 主流平板电脑方案深度剖析之ARMv5,v6,v7架构阵营

一、全文框架 按阵营分为&#xff1a; Ⅰ、ARMv5架构阵营&#xff0c;代表核心&#xff1a; ARM9核心 Ⅱ、ARMv6架构阵营&#xff0c;代表核心&#xff1a; ARM11核心 Ⅲ、ARMv7架构阵营&#xff0c;代表核心&#xff1a; ① 高通Scorpion核心 ②Cortex A8核心 ③三星Hummi…

在上海创业的日子之设备采购教训

在这里我向大家说一下&#xff0c;设备采购上的教训。 在创业之初毋庸置疑&#xff0c;本身钱就不多&#xff0c;但是花钱的地方却不少&#xff0c;但是采购设备尤其是电脑&#xff0c;前往别太省那几百块钱&#xff0c;下面来听我的故事。 刚开始创业&#xff0c;程序员嘛&a…

计算机制图用什么图纸,制图用什么笔记本好

以前人们常说的绘画都是在纸上&#xff0c;然而科技时代的到来也让绘画的方式有了改变&#xff0c;而且现实中还在发展电子商务&#xff0c;因此大家都开始使用计算机制图&#xff0c;不同的计算机制图的方式不一样&#xff0c;专业使用电脑制图的人都会对电脑比较挑剔。它们还…

华硕A455LD4210国美报价3550 下单附送鼠标等

目前&#xff0c;该本在深圳电子市场网在线报价3550元&#xff0c;下单还送华硕包鼠&#xff0c;喜欢的朋友不妨多关注一下。 一、华硕A455LD4210表现全能 华硕A455LD4210笔记本采用复合材质外壳&#xff0c;屏幕方面搭载一块14英寸16:9的LED背光屏&#xff0c;分辨率为1366768…

关于买衣服

李小兔&#xff1a;老公乖拉&#xff0c;表达你喜欢我的方式有很多种&#xff0c;我最不赞成的就是买东西给我… 你可以送我本书啊或者好玩的&#xff0c;价格在不浪费的范围内&#xff0c;我就会超开心了。 lxiaoxiaot&#xff1a;&#xff08;大笨蛋&#xff0c;别的女生都挣…

公寓这个大坑,劝大家不要再跳了

2019-05-22 11:49:31 一. 公寓能不能投资&#xff1f;真的是太多粉丝问这个问题了。 公寓就像一个磨人的小妖精&#xff0c;不少人明知道它有缺点——产权时间短、没有户口和学位、转手还要承担高额税费&#xff0c;还是奈何经受不了“不限购限贷、户型小低总价”的诱惑&#x…