个人公众号做网站/百度营销中心

个人公众号做网站,百度营销中心,常德本地网络论坛,软装设计师目录 单调队列 使用单调队列维护滑动窗口 具体过程: 代码实现: 复杂度分析: 使用单调队列优化动态规划 例题 单调队列 单调队列(deque)是一种特殊的队列,队列中的元素始终按严格递增或者递减排列。这样就可以保证队头元素…

目录

单调队列

使用单调队列维护滑动窗口

具体过程:

代码实现: 

复杂度分析:

使用单调队列优化动态规划

例题 


单调队列

单调队列(deque)是一种特殊的队列,队列中的元素始终严格递增或者递减排列。这样就可以保证队头元素始终是最大值或者最小值。

【问题引入】

有一个数组,长度为n,给你一个区间[left,right],求出该区间内的最小值或者最大值。

我们如果进行普通的遍历,最坏的情况下时间复杂度是O(N),遍历整个数组。

而我们如果用单调队列来维护这段区间,始终保持队列的单调性,就可以在O(1)的时间内找到该区间的最大值或者最小值,就是队头元素

【结论】

所以单调队列的核心用途是高效维护动态窗口的极值(最大值或最小值)。

那么对于一些动态规划,如转移方程需要进行一段区间的最值计算,可以使用单调队列优化。


使用单调队列维护滑动窗口

题目链接:239. 滑动窗口最大值 - 力扣(LeetCode)

当窗口形成后,我们需要找到这段窗口中的最大值,暴力的方法就是对这段区间进行遍历,每个元素进行比较,选出最大值。这样做时间复杂度为O(N^2),效率太低。

使用单调队列优化:单调队列维护该窗口,队头元素为最大元素。时间复杂度为O(N)。

具体过程:

  • 创建一个单调对列,维护该队列的递减性,以保证对头元素为窗口中的最小值
  • 对于该单调队列,存放元素的下标,按值递减排列。新来一个元素(也就是滑动窗口右移一步),需要判断对头元素是否还在窗口内,所以记录下标,便于判断对头元素是否还在窗口中,如果不在,删除对头元素。
  • 新来一个元素(也就是滑动窗口右移一步),每次都需要比较队尾元素与当前元素的大小,我们维护的是递减队列,如果队尾元素大于当前元素,则将当前元素的下标直接加入队列;如果队尾元素小于当前元素,则将队尾元素删除,直到队尾元素大于当前元素,再将当前元素下标加入队列,保持队列的递减性。
  • 窗口形成后,统计结果即可。队头元素就是最大元素。

代码实现: 

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {//双端队列 存储数组索引deque<int> dq;vector<int> res;for(int i=0;i<nums.size();i++){//移除超出范围的队首元素while(!dq.empty()&&dq.front()<=i-k)dq.pop_front();//维护队列递减性(从队头到队尾),移除所有小于当前元素的队尾元素 while(!dq.empty()&&nums[dq.back()]<nums[i])dq.pop_back();//当前元素入队列dq.push_back(i);//窗口形成后,统计结果,队头元素就是最大元素if(i>=k-1)res.push_back(nums[dq.front()]);}return res;}
};

 上面的写法是使用库中的deque,还可以使用数组来模拟:


#include<iostream>
using namespace std;
const int N = 1e6 + 5;int a[N], q[N];
int n, k;int main()
{cin >> n >> k;for (int i = 1; i <= n; i++) cin >> a[i];int hh = 0, tt = -1;for (int i = 1; i <= n; i++){while (hh <= tt && i - k >= q[hh]) hh++;//处理队首while (hh <= tt && a[q[tt]] <= a[i]) tt--;//处理队尾q[++tt] = i;//队尾元素加入if (i >= k) cout << a[q[hh]] << " ";//输出队首元素}cout << endl;return 0;
}

复杂度分析:

每个元素最多入队和出队一次,时间复杂度为O(N),队列最多存储k个元素,时间复杂度为O(K)。 


使用单调队列优化动态规划

在动态规划中,当状态转移需要在一个窗口查找极值时,可以使用单调队列优化时间复杂度。

题目链接:P5858 「SWTR-3」Golden Sword - 洛谷

状态表示:dp[i][j]表示加入第i个材料时, 锅内的材料个数为j(包括此时加入的),此时的耐久度的最大值。

状态转移方程的分析:加入第i个材料后的最大耐久度,等于加入第i-1个材料时最大的耐久度,再加上自身的耐久度,也就是再加上a[i]*j。

状态转移方程:dp[i][j]=max(dp[i][j],dp[i-1][k]+j*a[i]),j-1<=k<=min(w,j-1+s)。

正常使用动态规划:

第一层循环遍历i。

第二层循环遍历j,填写dp[i][j]。

但是由于有求[j-1,min(w,j-1+s)]最大值的操作,所以还需一层循环求最大值。

共三层循环,时间复杂度太大,需要进行优化。

#include <iostream>
using namespace std;
long long n, m, s;
long long a[5505];
long long dp[5505][5505];int main()
{cin >> n >> w >> s;for (long long i = 1; i <= n; i++)cin >> a[i];for (long long i = 0; i <= n; i++)for (long long j = 0; j <= w; j++)dp[i][j] = -1e18;dp[0][0] = 0;//dp[i][j]选第i个材料时,此时正好j个材料的最大耐久度for (long long i = 1; i <= n; i++)for (long long j = 1; j <= w; j++)for (long long k = j - 1; k <= min(w, s + j - 1); k++)dp[i][j] = max(dp[i][j], dp[i-1][k] + a[i] * j);long long ans = -1e18;for (int i = 0; i <= w; i++)ans = max(ans, dp[n][i]);cout << ans << endl;return 0;
}

使用单调队列优化后

在第三层的遍历,求区间[j-1,min(w,j-1+s)]的最大值,可以使用单调队列优化,降低时间复杂度。

//单调队列优化
#include <iostream>
#include <deque>
using namespace std;
long long n, w, s;
long long a[5505];
long long dp[5505][5505];int main()
{cin >> n >> w >> s;for (long long i = 1; i <= n; i++)cin >> a[i];for (long long i = 0; i <= n; i++)for (long long j = 0; j <= w; j++)dp[i][j] = -1e18;dp[0][0] = 0;//dp[i][j]选第i个材料时,此时正好j个材料的最大耐久度for (long long i = 1; i <= n; i++){deque<long long> q;  //单调队列,记录区间最大值  存储索引q.push_back(w);      //下面循环中w不会进队列,需提前进队列//[j-1,min(j-1+s,w)]//从右向左遍历,因为左端点固定,而右端点使用了minfor (long long j = w; j >= 1; j--){//[j-1,min(j-1+s,w)]while (!q.empty() && q.front() > min(w, s + j - 1))q.pop_front();while (!q.empty() && dp[i - 1][q.back()] < dp[i - 1][j-1])q.pop_back();q.push_back(j-1); //比较的是q.back()和j-1位置//统计结果dp[i][j] = a[i] * j + dp[i - 1][q.front()];}}long long ans = -1e18;for (int i = 0; i <= w; i++)ans = max(ans, dp[n][i]);cout << ans << endl;return 0;
}

例题 

题目链接:1438. 绝对差不超过限制的最长连续子数组 - 力扣(LeetCode) 

 使用两个单调队列来维护窗口的最大值和最小值,结合递增队列和递减队列。当最大值减最小值超出给定的limit时,窗口的左边界右移动,直到找到符合的位置,统计结果。

class Solution {
public:int longestSubarray(vector<int>& nums, int limit) {//单调队列,维护当前窗口的最大值和最小值deque<int> queMax,queMin;int n=nums.size();int left=0,right=0,ret=0;while(right<n){//维护队列的单调性//递减while(!queMax.empty()&&queMax.back()<nums[right])queMax.pop_back();//递增while(!queMin.empty()&&queMin.back()>nums[right])queMin.pop_back();//入队列元素queMin.push_back(nums[right]);queMax.push_back(nums[right]);while(!queMin.empty()&&!queMax.empty()&&queMax.front()-queMin.front()>limit){if(nums[left]==queMin.front())queMin.pop_front();if(nums[left]==queMax.front())queMax.pop_front();left++;}ret=max(ret,right-left+1);right++;}return ret;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习每周学习总结Y1(Yolov5 调用官方权重进行检测 )

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客Y1中的内容 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 ** 注意该训练营出现故意不退押金&#xff0c;恶意揣测偷懒用假的结果冒充真实打卡记录&#xff0c;在提出能够拿到视频录像…

为AI聊天工具添加一个知识系统 之117 详细设计之58 思维导图及观察者效应 之2 概念全景图

&#xff08;说明&#xff1a;本文和上一篇问题基本相同&#xff0c;但换了一个模型 deepseek-r1&#xff09; Q1227、在提出项目“为使用AI聊天工具的聊天者加挂一个专属的知识系统”后&#xff0c;我们已经进行了了大量的讨论-持续了近三个月了。这些讨论整体淋漓尽致体现了…

2012年IMO几何预选题第6题

设有非等腰的 △ A B C \triangle ABC △ABC, O O O 和 I I I 分别为外心和内心. 在边 A C AC AC, A B AB AB 上分别存在两点 E E E 和 F F F, 使得 C D C E A B CDCEAB CDCEAB, B F B D A C BFBDAC BFBDAC. 设 ( B D F ) (BDF) (BDF) 和 ( C D E ) (CDE) (CDE)…

为Eclipse IDE安装插件IBM编程助手watsonx Code Assistant

从Eclipse IDE 安装 从Eclipse IDE 安装插件&#xff1a; _1、在Eclipse IDE 中&#xff0c;单击帮助菜单&#xff0c;然后选择EclipseMarketplace。 _2、根据您计划进行的工作类型选择安装方式&#xff1a; 有关代码建议、代码解释、代码文档和单元测试的集成生成式人工智能&a…

Linux基本指令(三)+ 权限

文章目录 基本指令grep打包和压缩zip/unzipLinux和windows压缩包互传tar&#xff08;重要&#xff09;Linux和Linux压缩包互传 bcuname -r常用的热键关机外壳程序 知识点打包和压缩 Linux中的权限用户权限 基本指令 grep 1. grep可以过滤文本行 2. 把包含9的文本行过滤出来了 …

【部署优化篇十四】【十万字全景拆解:GitHub Actions自动化流水线设计圣经(DeepSeek工业级实践大公开)】

一、从手工作坊到智能工厂:CI/CD的革命之路 想象一下,你所在的公司每天要手工组装1000台手机,每个环节都靠老师傅肉眼检查——这就是没有CI/CD的软件开发现状。GitHub Actions的出现,就像给软件交付装上了特斯拉的超级工厂流水线。 DeepSeek的CI/CD演进史就是一部血泪史:…

【精调】LLaMA-Factory 快速开始1: Meta-Llama-3.1-8B-Instruct

llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml llamafactory-cli chat examples/inference/llama3_lora_sft.yaml llamafactory-cli export examples/merge_lora/llama3_lora_sft.yaml模型下载 git clone https://www.modelscope.cn/LLM-Research/Meta-Lla…

【07】区块链性能

7-1 基础性能优化 7-1-1 区块链性能瓶颈 总述 区块链性能指标 区块链的性能指标主要包括&#xff1a; 吞吐量&#xff1a;在固定时间内处理的交易数量 延时&#xff1a;对交易的响应和处理时间 主流区块链与中心化平台TPS对比 区块链与传统计算的对比 区块链可信且中立…

安全面试2

文章目录 简单描述一下什么是水平越权&#xff0c;什么是垂直越权&#xff0c;我要发现这两类漏洞&#xff0c;那我代码审计要注意什么地方水平越权&#xff1a;垂直越权&#xff1a;水平越权漏洞的审计重点垂直越权漏洞的审计重点 解释一下ssrf漏洞原理攻击场景修复方法 横向移…

【Linux 专栏】echo命令实验

风123456789&#xff5e;-CSDN博客 最近文章阅读排行榜 【爬虫基础】第一部分 网络通讯 P1/3-CSDN博客 【爬虫基础】第一部分 网络通讯-Socket套接字 P2/3-CSDN博客 【Linux专栏】find命令同步 实验-CSDN博客 【Linux运维】非root用户的单向免密登录_linux 单向免密-CSDN博客…

qt5实现表盘的旋转效果,通过提升QLabel类

因为工作需要&#xff0c;需要实现温度的表盘展示效果 实现思路&#xff1a; 通过提示声QLabel控价类&#xff0c;实现报盘的旋转和展示效果 1. 编写一个QLabel的类MyQLabel,实现两个方法 1. void paintEvent(QPaintEvent *event); //重绘函数 2. void valueChanged(int va…

【深度学习】Pytorch的深入理解和研究

一、Pytorch核心理解 PyTorch 是一个灵活且强大的深度学习框架&#xff0c;广泛应用于研究和工业领域。要深入理解和研究 PyTorch&#xff0c;需要从其核心概念、底层机制以及高级功能入手。以下是对 PyTorch 的深入理解与研究的详细说明。 1. 概念 动态计算图&#xff08;D…

002 SpringCloudAlibaba整合 - Feign远程调用、Loadbalancer负载均衡

前文地址&#xff1a; 001 SpringCloudAlibaba整合 - Nacos注册配置中心、Sentinel流控、Zipkin链路追踪、Admin监控 文章目录 8.Feign远程调用、loadbalancer负载均衡整合1.OpenFeign整合1.引入依赖2.启动类添加EnableFeignClients注解3.yml配置4.日志配置5.远程调用测试6.服务…

代码审计入门学习之sql注入

路由规则 入口文件&#xff1a;index.php <?php // ---------------------------------------------------------------------- // | wuzhicms [ 五指互联网站内容管理系统 ] // | Copyright (c) 2014-2015 http://www.wuzhicms.com All rights reserved. // | Licensed …

React实现自定义图表(线状+柱状)

要使用 React 绘制一个结合线状图和柱状图的图表&#xff0c;你可以使用 react-chartjs-2 库&#xff0c;它是基于 Chart.js 的 React 封装。以下是一个示例代码&#xff0c;展示如何实现这个需求&#xff1a; 1. 安装依赖 首先&#xff0c;你需要安装 react-chartjs-2 和 ch…

springboot整合mybatis-plus【详细版】

目录 一&#xff0c;简介 1. 什么是mybatis-plus2.mybatis-plus特点 二&#xff0c;搭建基本环境 1. 导入基本依赖&#xff1a;2. 编写配置文件3. 创建实体类4. 编写controller层5. 编写service接口6. 编写service层7. 编写mapper层 三&#xff0c;基本知识介绍 1. 基本注解 T…

HTTP 常见状态码技术解析(应用层)

引言 HTTP 状态码是服务器对客户端请求的标准化响应标识&#xff0c;属于应用层协议的核心机制。其采用三位数字编码&#xff0c;首位数字定义状态类别&#xff0c;后两位细化具体场景。 状态码不仅是服务端行为的声明&#xff0c;更是客户端处理响应的关键依据。本文将从协议规…

Unity中的键位KeyCode

目录 主要用途 检测按键事件&#xff1a; 处理键盘输入&#xff1a; 基本键位 常用键&#xff1a; 字母键&#xff1a; 数字键&#xff1a; 功能键&#xff1a; 方向键&#xff1a; 控制键&#xff1a; 鼠标键&#xff1a; 其他特殊键&#xff1a; 代码示例 按下…

【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式 代理模式是一种结构型设计模式&#xff0c;它提供了一种替代访问的方法&#xff0c;即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下&#xff0c;增加额外的功能&#xff0c;如权限控制、日志记录等。 静态代理 静态代理是指创建的或特…

Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)

Android Coil3缩略图、默认占位图placeholder、error加载错误显示&#xff0c;Kotlin&#xff08;1&#xff09; implementation("io.coil-kt.coil3:coil-core:3.1.0")implementation("io.coil-kt.coil3:coil-network-okhttp:3.1.0") <uses-permission …