代码随想录算法训练营day13|239.滑动窗口最大值、347.前K个高频元素

微信小程序 | 小程序开发 事实上,目前小程序在我们生活中已经随处可见(特别是这次疫情的推动,不管是什么岗位、什么年龄阶段的人,到哪都需要打开健康码)WePY是由腾讯开源的,一款让小程序支持组件化开发的框架,通过预编译的手段让开发者可以选择自己喜欢的开发风格去开发小程序。Mpvue是一个使用Vue开发小程序的前端框架,也是 支持 微信小程序、百度智能小程序,头条小程序 和 支付宝小程序;微信小程序、支付宝小程序、淘宝小程序、抖音小程序、头条小程序、QQ小程序、美团小程序等。,其他平台的小程序往往是平台本身的一些公司或者顺手开发的。 阅读详情

滑动窗口最大值

暴力解法

        会超时,计算每个窗口内最大值,并将其加入最后的窗口最大值数组。这里我有使用一些剪枝,但仍会超时。具体代码如下。算法的时间复杂度为O(n*k),空间复杂度为O(n-k+1),简化为O(n)。

class Solution {
public:
    // 辅助函数,用于找到从begin到end索引范围内的最大值
    int find_max(vector<int>& nums, int begin, int end) {
        int max = -10000; // 初始化最大值为一个很小的数
        for (int i = begin; i <= end; i++) { // 遍历begin到end之间的所有元素
            if (nums[i] > max) { // 如果当前元素大于max,则更新max
                max = nums[i];
            }
        }
        return max; // 返回最大值
    }

    // 主函数,用于求解滑动窗口的最大值序列
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ans; // 创建一个空向量,用于存储每个窗口的最大值
        int left = 0; // 初始化窗口的左边界
        int right = k - 1; // 初始化窗口的右边界(k-1是初始窗口的最后一个元素的索引)
        int max = find_max(nums, left, right); // 找到初始窗口的最大值
        for (int i = 0; i <= nums.size() - k; i++) { // 遍历所有可能的窗口
            if (left == 0) { // 如果是第一个窗口,直接将最大值加入答案
                ans.push_back(max);
                left++; // 窗口左边界向右移动
                right++; // 窗口右边界向右移动
            }
            else if (left > 0 && nums[left - 1] != max && nums[right] < max) { // 如果左边界不是第一个元素,且离开的元素不是最大值,且新加入的元素小于最大值
                ans.push_back(max); // 保持最大值不变,加入答案
                left++; // 窗口左边界向右移动
                right++; // 窗口右边界向右移动
            }
            else { // 其他情况,需要重新找到当前窗口的最大值
                max = find_max(nums, left, right); // 重新找到当前窗口的最大值
                ans.push_back(max); // 将最大值加入答案
                left++; // 窗口左边界向右移动
                right++; // 窗口右边界向右移动
            }
        }
        return ans; // 返回最大值序列
    }
};

单调队列

单调队列 滑动窗口最大值【基础算法精讲 27】_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1bM411X72E/?spm_id_from=333.337.search-card.all.click&vd_source=fc4a6e70e3a87b7ea67c2024e326e7c5这个视频里对飞机在飞机上从上往下看找高山的例子我感觉很形象。

这里寻找最大值,将可能的最大值存入双端队列中,每次移动都先判断其是否有可能成为最大值,即若队列非空,它比队列中队首的数小(因为队首的数在下一次移动会弹出),但比它入队前的队尾要大,则将队尾弹出,将它入队,形成一个有序的双端队列。

我们需要一个数据结构,能够实现(双端队列)

  • 移除最左边的元素
  • 移除最右边的元素
  • 在最右边插入元素

以及(单调性)

  • 从队首到队尾单调递减

即一个单调队列。代码如下。

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ans; // 存储结果的数组
        deque<int> dq; // 双端队列,用于存储可能的最大值候选

        for (int i = 0; i < nums.size(); ++i) {
            // 移除窗口之外的元素索引
            while (!dq.empty() && dq.front() < i - k + 1) {
                dq.pop_front();
            }
            // 移除所有小于当前元素的索引,保证队列是单调递减的
            while (!dq.empty() && nums[dq.back()] < nums[i]) {
                dq.pop_back();
            }
            // 将当前元素索引加入队列
            dq.push_back(i);
            // 当窗口形成时,将最大值加入结果数组
            if (i >= k - 1) {
                ans.push_back(nums[dq.front()]);
            }
        }

        return ans;
    }
};

算法的时间复杂度为O(n),空间复杂度为O(k)。

前K个高频元素

哈希表加快排

        首先创建了一个 unordered_map 来存储每个元素及其出现的频率。然后,将 map 中的键值对复制到一个 vector 中。接下来,我们使用 sort 函数对 vector 进行排序,排序的依据是键值对的第二个元素(即频率),排序完成后,我们创建了一个 vector ans 来存储前 k 个高频元素的键。我们遍历排序后的 vector,将前 k 个元素的键放入 ans 中。

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // 创建一个哈希map来存储元素及其出现频数
        unordered_map<int, int> freq;
        for (int num : nums) {
            freq[num]++;
        }

        // 将map中的键值对存储到vector中
        vector<pair<int, int>> freqVec(freq.begin(), freq.end());

        // 根据频率对键值对进行排序
        sort(freqVec.begin(), freqVec.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
            return a.second > b.second; // 按照频率降序排序
        });

        // 创建答案数组
        vector<int> ans(k);
        // 将前k个高频元素的键放入答案数组
        for (int i = 0; i < k; ++i) {
            ans[i] = freqVec[i].first;
        }

        return ans;
    }
};

算法的时间复杂度为O(nlogn),空间复杂度为O(n)。

哈希表加最小堆

        我们首先使用unordered_map来统计每个元素的出现频率。然后,利用一个最小堆来维护频率最高的k个元素。每次从哈希表中取出一个元素,就将其插入到堆中,如果堆的大小超过了k,我们就弹出堆顶元素,这样堆中始终维护的是频率最高的k个元素。最后,我们将堆中的元素取出到答案数组中,由于堆是最小堆,所以我们需要从后往前填充数组,以确保数组是按照频率从高到低排序的。

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // 创建一个哈希map来存储元素及其出现频数
        unordered_map<int, int> freq;
        for (int num : nums) {
            freq[num]++;
        }

        // 创建一个最小堆,用于存储频率最高的k个元素
        // 堆中的元素是pair,first是频率,second是元素值
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> minHeap;

        // 遍历哈希表,将元素插入堆中
        for (auto& pair : freq) {
            minHeap.push(make_pair(pair.second, pair.first));
            // 如果堆的大小超过k,弹出堆顶元素(频率最小的)
            if (minHeap.size() > k) {
                minHeap.pop();
            }
        }

        // 从堆中取出元素到答案数组中
        vector<int> ans(k);
        for (int i = k - 1; i >= 0; --i) {
            ans[i] = minHeap.top().second;
            minHeap.pop();
        }

        return ans;
    }
};

时间复杂度O(nlogk),k为堆的大小,空间复杂度O(n)

10.嵌入式控制器EC实战 GPIO开发流程 文章目录1.General Control Register (GCR),通用控制寄存器,地址0x1602.GPDRA—GPDRJ端口数据寄存器组(共10组)3.Port Control n Registers (GPCRn, n = A0-I7),端口控制寄存器4.GPIO端口编程指导编程步骤端口初始化使用InitGPIOReg数据结构初始化所有端口默认工作模式读取输入引脚的值(STATE_ACin()): IT8502中各个引脚的描述见下表所示: 在嵌入式控制器EC的IT8502主控芯片中,通过芯片的 阅读详情

相关推荐

UReport2 报表设计器 在线表格

UReport2官网 一、UReport2报表设计器 UReport2是一个开源的可视化报表设计器,功能强大,操作简单,可以实现复杂的报表统计,有各种各样的导出和打印功能,支持导入Excel表格! 1、报表设计器 2、设计一个简单的用户列表展示 二、可编辑表格 扩展了layui的表格,支持多元化数据编辑(单选,多些、日期、下拉联动),开发简单、高效、便捷。有了它就可以轻松开发类似进销存系统的表格录入功能了,用户拿来即用! 三、主从表录......

ejinxian的专栏 2万+

代码随想录算法训练营 day13 || 239. 滑动窗口最大值,347. 前K个高频元素

解题状态:第一题在有了单调队列的思路后自行实现;第二题未能解出。239. 滑动窗口最大值思路:本题官方题解以及代码随想录所给出的代码中都用到了Deque这种双向队列,双向队列是一种首尾皆可出队与入队的特殊队列。这种工具非常值得学习,特别是我这个不会的人。回到这道题,由于我对双向队列的陌生,我认为与大多数栈与队列题目类似,栈与队列仅仅是一种数据存储的工具,因此可以采用任何容器结合静态指针实现栈与队列的模拟,甚至在一定程度上,会比声明Stack与Queue结构来的更加具有时间效率。

旭 1056

Qt中多线程的使用(一)

我们要实现的是读取大文件qtgui.index的内容加入文本框中。 很容易想到的方法: QFile* file = new QFile("E:\qtgui.index"); file-&gt;open(QIODevice::ReadOnly); QTextStream *stream = new QTextStream(file); while(!st...

yao5hed的专栏 1万+

代码随想录算法训练营day13 | 239. 滑动窗口最大值、347.前 K 个高频元素

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

weixin_69675605的博客 1143

PINN——加入物理约束的神经网络

【摘要】 基于物理信息的神经网络(Physics-informed Neural Network, 简称PINN),是一类用于解决有监督学习任务的神经网络,它不仅能够像传统神经网络一样学习到训练数据样本的分布规律,而且能够学习到数学方程描述的物理定律。与纯数据驱动的神经网络学习相比,PINN在训练过程中施加了物理信息约束,因而能用更少的数据样本学习到更具泛化能力的模型。本文主要解析这种神经网络以...

qq_39444290的博客 4582

RedHat 9 替换yum源镜像

引言:我们个人通常使用的红帽系统yum源是需要注册付费的,所以在使用yum源安装一些软件时无法正常安装(例如:MySQL),这时我们就需要将yum源替换为CentOS对应的源,以实现在红帽系统中正常安装软件。

YUJIAOZHU666的博客 3737

代码随想录算法训练营day13● 239. 滑动窗口最大值● 347.前 K 个高频元素● 总结

然后加入-3,前面的元素都比-3大,此时的最大值还是出口处的元素3。接下来,滑动窗口向后移动,pop3,加入5,前面的元素都比5小,将前面的元素都弹走,此时最大元素为出口处的5。接下来加入3,最大值为5,加入2,最大值为5。再向后移动,pop5,push1,最大值为3。最大值:{3,3,5,5,5,3}

m0_74845823的博客 1483

差分隐私(Differential Privacy)

差分隐私,拉普拉斯机制和高斯机制的证明

Michale_L的博客 1万+

代码随想录算法训练营 DAY 13 | 239.滑动窗口最大值 347.前 K 个高频元素

比较一下队列和栈相关方法的不同:队列:add():在队尾添加元素remove():删除并返回队头isEmpty():是否为空栈:push():压入元素pop():弹出栈顶元素,并返回栈顶元素peek():返回栈顶元素empty():是否为空其他求长度size(),求堆头/栈顶peek()和清空clear()都是一样的!注意在java中,栈是一个实现类。而队列是一个接口,实现类有LinkedList和PriorityQueue关于deque队头元素:deque.peek()

qq_35904005的博客 964

从零配置XDMA:手把手教你PCIe BAR与AXI总线的地址转换(基于Vivado2023)

本文基于Vivado2023,手把手教你配置XDMA IP核,深入解析PCIe BAR与AXI总线地址转换的核心原理。通过实战步骤,详细说明如何正确设置BAR参数(如32/64位、预取使能)及地址映射,确保主机能稳定访问FPGA侧寄存器与内存,是解决PCIe通信调试难题的关键指南。

2w3e4r5t6y的博客 1211

手把手教你用RK3568开发板实现FPGA与Linux的DMA通信(含完整代码解析)

本文详细介绍了如何在RK3568开发板上实现FPGA与Linux系统的DMA通信,包括硬件配置、软件环境搭建、DMA通信原理、驱动开发及性能优化。通过完整的代码解析和实战案例,帮助开发者快速掌握异构系统间的高效数据传输技术,适用于物联网和边缘计算等场景。

weixin_29174385的博客 201

代码随想录算法训练营第day13|239. 滑动窗口最大值、 347.前 K 个高频元素

寻找前k个最大元素流程如图所示:(图中的频率只有三个,所以正好构成一个大小为3的小顶堆,如果频率更多一些,则用这个小顶堆进行扫描)

qq_60513199的博客 891

如何用 Claude Code 做代码重构,而不是重写

摘要: 在使用Claude Code进行代码优化时,AI容易“重写”而非“重构”,导致改动过大、review困难。本文提出3个关键约束方法:1)限制修改范围(如仅修改指定函数);2)明确不改变代码行为;3)要求最小必要修改。通过分步骤重构、先获取重构建议再修改、使用标准模板(保持函数签名/输入输出/结构不变)等方式,可使AI输出更符合工程需求的小范围安全重构。对于彻底混乱的代码,才建议直接重写。核心在于通过提示词精准约束AI的修改行为,将其转化为高效的代码重构助手。

sg_knight的专栏 980

【Leetcode】-代码随想录算法训练营Day13|239. 滑动窗口最大值,347.前 K 个高频元素

思路分析+图解+代码,解析单调队列和优先级队列 Leetcode - 239. 滑动窗口最大值,347.前 K 个高频元素

weixin_45364118的博客 1812

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

代码随想录算法训练营Day13|239滑动窗口最大值 347前k个高频元素

学习了Carl的视频。

luyimin87的博客 439

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

代码随想录算法训练营day13|| 239. 滑动窗口最大值、347.前 K个高频元素、总结

寻找前k个最大元素流程如图所示:(图中的频率只有三个,所以正好构成一个大小为3的小顶堆,如果频率更多一些,则用这个小顶堆进行扫描)大家对这个比较运算在建堆时是如何应用的,为什么左大于右就会建立小顶堆,反而建立大顶堆比较困惑。确实 例如我们在写快排的cmp函数的时候,

qq_40222433的博客 695

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

代码随想录算法训练营Day13|Leetcode239滑动窗口最大值、Leetcode347前 K 个高频元素、总结

Day13打卡!今日感想:今天主要是队列相关的题,给栈和队列这章做个收尾。代码结合着解题思路能大致读懂,还是需要再复习一下的~💪

m0_60979177的博客 1450

代码随想录算法训练营Day13|239.滑动窗口最大值、347.前 K 个高频元素

代码随想录算法训练营Day13|239.滑动窗口最大值、347.前 K 个高频元素

qq_41929830的博客 444

Carl代码随想录算法训练营-Day 13-239. 滑动窗口最大值、347.前 K 个高频元素

算法训练营日常学习记录。本文分享了两道leetcode题目:239. 滑动窗口最大值和347.前 K 个高频元素的解题方法,详细分析了思路,并给出了具体的Java代码实现。

BuleFACE_Zhang的博客 531

代码随想录算法训练营Day13—— 239滑动窗口最大值、347前K个高频元素

239题滑动窗口最大值考虑队列 总结 时间复杂度:O(n)O(n)O(n) 空间复杂度:O(k)O(k)O(k)347题前K个高频元素三步走:统计元素出现频率、对频率排序、找出前K个高频元素 优先级队列 总结 时间复杂度:O(n∗logk)O(n*log k)O(n∗logk) 空间复杂度:O(n)O(n)O(n)

weixin_45075561的博客 277

代码随想录算法训练营day13| 239. 滑动窗口最大值、347.前 K 个高频元素

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

weixin_45368277的博客 1830

代码随想录算法训练营 day13 | 239. 滑动窗口最大值 、347. 前K个高频元素

其实就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。而且优先级队列内部元素是自动依照元素的权值排列。那么它是如何有序排列的呢?缺省情况下priority_queue利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树)。堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。

weixin_42179093的博客 299

代码随想录算法训练营Day13 | 239. 滑动窗口最大值、347.前 K 个高频元素、栈与队列总结 | Python | 个人记录向

栈与队列:239. 滑动窗口最大值、347.前 K 个高频元素、总结。算法:双端单调队列、优先级队列。

Python基本算法 949

代码随想录算法训练营Day13|239. 滑动窗口最大值、347.前 K 个高频元素

单调队列登场!初步了解大顶堆、小顶堆的数据结构和作用。今天两道题目难度有点略高,单调队列、小顶堆大顶堆对于新手小白都是一些没怎么了解的内容,可能学完二叉树章节再回过来看就会好很多,继续坚持打卡!

m0_68682181的博客 810

代码随想录算法训练营Day13 | 239. 滑动窗口最大值 347.前 K 个高频元素

思路:1.构建自定义队列(单调队列);2. 每次push前将小于push的值pop;3. 单调递增的数列。

qq_24817679的博客 410

代码随想录算法训练营day13 | 239. 滑动窗口最大值,347.前 K 个高频元素

时间复杂度O(n)自定义队列要实现三个功能:1、返回最大值2、存入元素3、弹出元素//创建结果数组 int length = nums . length - k + 1;//将前k的元素放入队列 for(int i = 0;i < k;i ++) {i ++) {//这里输入滑窗出口数据 myQueue . push(nums [ i ]);//这里输入滑窗入口数据 result [ i - k + 1 ] = myQueue . getMaxValue();

2301_77450803的博客 129
上一篇: 代码随想录 哈希表总结 C++
下一篇: 代码随想录算法训练营day14|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法
viaNoir
博客等级 码龄10年 535粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值