算法刷题day22:双指针
目录
- 引言
- 概念
- 一、牛的学术圈I
- 二、最长连续不重复序列
- 三、数组元素的目标和
- 四、判断子序列
- 五、日志统计
- 六、统计子矩阵
引言
关于这个双指针算法,主要是用来处理枚举子区间的事,时间复杂度从 O ( N 2 ) O(N^2) O(N2) 降为 O ( N ) O(N) O(N) ,所以还是很方便的,而且枚举这类题出的还是很常见的,所以这个算法还是尤为重要的。加油!
概念
双指针算法:首先要满足单调性,二分是元素的单调性、二段性,这个指的是区间的单调性。
双指针模板:
for(int i = 0, j = 0; i < n; ++i)
{while(j < n && check(i,j)) j++;//该题逻辑
}
一、牛的学术圈I
标签:二分
思路:像这种求最大/最小的问题,基本上都可以用二分。我们不讨论最大值,我们讨论该h指数是否能达到,然后用二分来逼近能成立的最大值,显然该题是具有二段性的,具体长如下这样。然后就是 c h e c k check check 函数了,因为先统计大于等于 m i d mid mid 的个数,再统计满足 a [ i ] + 1 = m i d a[i] + 1 = mid a[i]+1=mid 的个数,与 l l l 取最小值,最后比较是否 r e s ≥ m i d res \geq mid res≥mid 。

题目描述:
由于对计算机科学的热爱,以及有朝一日成为 「Bessie 博士」的诱惑,奶牛 Bessie 开始攻读计算机科学博士学位。经过一段时间的学术研究,她已经发表了 N 篇论文,并且她的第 i 篇论文得到了来自其他研究文献的 ci 次引用。Bessie 听说学术成就可以用 h 指数来衡量。h 指数等于使得研究员有至少 h 篇引用次数不少于 h 的论文的最大整数 h。例如,如果一名研究员有 4 篇论文,引用次数分别为 (1,100,2,3),则 h 指数为 2,然而若引用次数为 (1,100,3,3)则 h 指数将会是 3。为了提升她的 h 指数,Bessie 计划写一篇综述,并引用一些她曾经写过的论文。由于页数限制,她至多可以在这篇综述中引用 L 篇论文,并且她只能引用每篇她的论文至多一次。请帮助 Bessie 求出在写完这篇综述后她可以达到的最大 h 指数。注意 Bessie 的导师可能会告知她纯粹为了提升 h 指数而写综述存在违反学术道德的嫌疑;我们不建议其他学者模仿 Bessie 的行为。输入格式
输入的第一行包含 N 和 L。
第二行包含 N 个空格分隔的整数 c1,…,cN。输出格式
输出写完综述后 Bessie 可以达到的最大 h 指数。数据范围
1≤N≤105,0≤ci≤105,0≤L≤105
输入样例1:
4 0
1 100 2 3
输出样例1:
2
样例1解释
Bessie 不能引用任何她曾经写过的论文。上文中提到,(1,100,2,3) 的 h 指数为 2。输入样例2:
4 1
1 100 2 3
输出样例2:
3
如果 Bessie 引用她的第三篇论文,引用数会变为 (1,100,3,3)。上文中提到,这一引用数的 h 指数为 3。
示例代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e5+10;int n, m;
int a[N];bool check(int mid) // 检查能否到mid
{int res = 0, t = 0;for(int i = 0; i < n; ++i){if(a[i] >= mid) res++;if(a[i] + 1 == mid) t++;}t = min(m, t);res += t;return res >= mid;
}int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> m;for(int i = 0; i < n; ++i) cin >> a[i];int l = 0, r = 1e5;while(l < r){int mid = (LL)l + r + 1 >> 1;if(check(mid)) l = mid;else r = mid - 1;}cout << r << endl;return 0;
}
二、最长连续不重复序列
标签:双指针
思路:模板题。核心就是 [ j , i ] [j,i] [j,i] 维护的是一段有效的序列, i i i 是一值往前走的,用 c n t cnt cnt 来记录每一个值出现的次数,如果重复了,那肯定是 i i i 和 j j j 所对应的元素重复了, j j j 往前走即可,然后找最大值。
题目描述:
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。数据范围
1≤n≤105
输入样例:
5
1 2 2 3 5
输出样例:
3
示例代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e5+10;int n;
int a[N], cnt[N];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n;for(int i = 0; i < n; ++i) cin >> a[i];int res = 0;for(int i = 0, j = 0; i < n; ++i){cnt[a[i]]++;while(j < i && cnt[a[i]] > 1) cnt[a[j++]]--;res = max(res, i - j + 1);}cout << res << endl;return 0;
}
三、数组元素的目标和
标签:哈希、双指针
思路1:就是找两个数组中和为 k e y key key 的两个下标,直接先把第一个数组按元素值存入哈希表,然后遍历第二个数组如果存在就输出即可。
思路2:由于都是升序的, i i i 从最小值遍历, j j j 从最大值遍历,如果值总和变小了, i i i 右移,如果变大了, j j j 左移,直到相等。
题目描述:
给定两个升序排序的有序数组 A 和 B,以及一个目标值 x。数组下标从 0 开始。请你求出满足 A[i]+B[j]=x 的数对 (i,j)。数据保证有唯一解。输入格式
第一行包含三个整数 n,m,x,分别表示 A 的长度,B 的长度以及目标值 x。第二行包含 n 个整数,表示数组 A。第三行包含 m 个整数,表示数组 B。输出格式
共一行,包含两个整数 i 和 j。数据范围
数组长度不超过 105。同一数组内元素各不相同。1≤数组元素≤109
输入样例:
4 5 6
1 2 4 7
3 4 6 8 9
输出样例:
1 1
示例代码1: 哈希表
#include <bits/stdc++.h>using namespace std;typedef long long LL;int n, m, k;
unordered_map<int,int> mmap;int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> m >> k;for(int i = 0; i < n; ++i){int t; cin >> t;mmap[t] = i;}for(int i = 0; i < m; ++i){int t; cin >> t;if(mmap.count(k-t)) {cout << mmap[k-t] << " " << i << endl;break;}}return 0;
}
示例代码2: 双指针
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e5+10;int n, m;
LL k;
int a[N], b[N];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> m >> k;for(int i = 0; i < n; ++i) cin >> a[i];for(int i = 0; i < m; ++i) cin >> b[i];int i = 0, j = m - 1;for(; i < n && j > -1; ++i){while(j > -1 && a[i] + b[j] > k) j--;if(j > -1 && (LL)a[i] + b[j] == k) break;}cout << i << " " << j << endl;return 0;
}
四、判断子序列
标签:双指针、模板题
思路:双指针模板,没啥说的。
题目描述:
给定一个长度为 n 的整数序列 a1,a2,…,an 以及一个长度为 m 的整数序列 b1,b2,…,bm。请你判断 a 序列是否为 b 序列的子序列。子序列指序列的一部分项按原有次序排列而得的序列,例如序列 {a1,a3,a5} 是序列 {a1,a2,a3,a4,a5} 的一个子序列。输入格式
第一行包含两个整数 n,m。
第二行包含 n 个整数,表示 a1,a2,…,an。
第三行包含 m 个整数,表示 b1,b2,…,bm。输出格式
如果 a 序列是 b 序列的子序列,输出一行 Yes。
否则,输出 No。数据范围
1≤n≤m≤105,109≤ai,bi≤109
输入样例:
3 5
1 3 5
1 2 3 4 5
输出样例:
Yes
示例代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e5+10;int n, m;
int a[N], b[N];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> m;for(int i = 0; i < n; ++i) cin >> a[i];for(int j = 0; j < m; ++j) cin >> b[j];int i = 0, j = 0;while(i < n && j < m){if(a[i] == b[j]) i++;j++;}if(i == n) puts("Yes");else puts("No");return 0;
}
五、日志统计
标签:枚举、双指针
思路:一般这种题都是遍历订单,而我看这道题要按 i d id id 号由小到大输出,那我就遍历 i d id id 号了,然后找出满足条件的输出就行了,我用 v e c t o r + 数组 vector+数组 vector+数组 来存,第 i i i 号 v e c t o r vector vector 代表 i d id id 号为 i i i 的订单时间, v e c t o r vector vector 里存的是该 i d id id 的点赞时间,首先如果数量够 k k k 个,然后由小到大排序,遍历每 k k k 个时间,判断是否间隔时间在 d d d 以内,如果是输出即可。
题目描述:
小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 N 行。其中每一行的格式是:ts id 表示在 ts 时刻编号 id 的帖子收到一个”赞”。现在小明想统计有哪些帖子曾经是”热帖”。如果一个帖子曾在任意一个长度为 D 的时间段内收到不少于 K 个赞,小明就认为这个帖子曾是”热帖”。具体来说,如果存在某个时刻 T 满足该帖在 [T,T+D) 这段时间内(注意是左闭右开区间)收到不少于 K 个赞,该帖就曾是”热帖”。给定日志,请你帮助小明统计出所有曾是”热帖”的帖子编号。输入格式
第一行包含三个整数 N,D,K。以下 N 行每行一条日志,包含两个整数 ts 和 id。输出格式
按从小到大的顺序输出热帖 id。每个 id 占一行。数据范围
1≤K≤N≤105,0≤ts,id≤105,1≤D≤10000
输入样例:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出样例:
1
3
示例代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e5+10;int n, d, k;
vector<int> logs[N]; // 统计第i号订单的日期int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> d >> k;for(int i = 0; i < n; ++i){int ts, id;cin >> ts >> id;logs[id].push_back(ts);}for(int i = 0; i < N; ++i) // 遍历每一个id{if(logs[i].size() >= k){sort(logs[i].begin(), logs[i].end()); // 给其时间排序for(int j = 0; j + k - 1 < logs[i].size(); ++j){if(logs[i][j+k-1] - logs[i][j] + 1 <= d) {cout << i << endl;break;}}}}return 0;
}
六、统计子矩阵
标签:前缀和、二分
思路:本来用前缀和直接做的话,时间复杂度在 O ( N 4 ) O(N^4) O(N4) ,明显超时了。由题意得元素没有负数,所以满足单调性,可以用上下界限拿前缀和处理,左右拿双指针处理,这样时间复杂度就降为了 O ( N 3 ) O(N^3) O(N3) 刚好能过。
题目描述:
给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?输入格式
第一行包含三个整数 N,M 和 K。之后 N 行每行包含 M 个整数,代表矩阵 A。输出格式
一个整数代表答案。数据范围对于 30% 的数据,N,M≤20,
对于 70% 的数据,N,M≤100,
对于 100% 的数据,1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5×108。输入样例:
3 4 10
1 2 3 4
5 6 7 8
9 10 11 12
输出样例:
19
样例解释
满足条件的子矩阵一共有 19,包含:大小为 1×1 的有 10 个。大小为 1×2 的有 3 个。大小为 1×3 的有 2 个。大小为 1×4 的有 1 个。大小为 2×1 的有 3 个。
示例代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 510;int n, m, k;
int s[N][N];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> n >> m >> k;for(int i = 1; i <= n; ++i){for(int j = 1; j <= m; ++j){cin >> s[i][j];s[i][j] += s[i-1][j];}}LL res = 0;for(int i = 1; i <= n; ++i){for(int j = i; j <= n; ++j){for(int l = 1, r = 1, sum = 0; r <= m; ++r){sum += s[j][r] - s[i-1][r];while(l <= m && sum > k) sum -= s[j][l] - s[i-1][l], l++;res += r - l + 1;}}}cout << res << endl;return 0;
}
相关文章:
算法刷题day22:双指针
目录 引言概念一、牛的学术圈I二、最长连续不重复序列三、数组元素的目标和四、判断子序列五、日志统计六、统计子矩阵 引言 关于这个双指针算法,主要是用来处理枚举子区间的事,时间复杂度从 O ( N 2 ) O(N^2) O(N2) 降为 O ( N ) O(N) O(N) …...
山人求道篇:八、模型的偏差与交易认知
原文引用https://mp.weixin.qq.com/s/xvxatVseHK62U7aUXS1B4g “ CTA策略一波亏完全年,除了交易执行错误导致的以外,这类策略都是多因子策略,一般会用机器学习组合多因子得出一个信号来进行交易。规则型策略几乎不会出现一波做反亏完全年的情况。这是有以下几个原因的: 多…...
MySQL 元数据锁及问题排查(Metadata Locks MDL)
"元数据"是用来描述数据对象定义的,而元数据锁(Metadata Lock MDL)即是加在这些定义上。通常我们认为非锁定一致性读(简单select)是不加锁的,这个是基于表内数据层面,其依然会对表的元…...
JS中的函数
1、函数形参的默认值 JavaScript函数有一个特别的地方,无论在函数定义中声明了多少形参,都可以传入任意数量的参数,也可以在定义函数时添加针对参数数量的处理逻辑,当已定义的形参无对应的传入参数时,为其指定一个默认…...
微信小程序开发常用的布局
在微信小程序开发中,常用的布局主要包括以下几种: Flex 布局:Flex 布局是一种弹性盒子布局,通过设置容器的属性来实现灵活的布局方式。它可以在水平或垂直方向上对子元素进行对齐、排列和分布。Flex 布局非常适用于创建响应式布局…...
Effective C++ 学习笔记 条款10 令operator=返回一个reference to *this
关于赋值,有趣的是你可以把它们写成连锁形式: int x, y, z; x y z 15; // 赋值连锁形式同样有趣的是,赋值采用右结合律,所以上述连锁赋值被解析为: x (y (z 15));这里15先被赋值给z,然后其结果&…...
算法简单试题
一、选择题 01.一个算法应该是( B ). A.程序 B.问题求解步骤的描述 C.要满足五个基本特性 D.A和C 02.某算法的时间复杂度为O(n),则表示该…...
CSS 自测题 -- 用 flex 布局绘制骰子(一、二、三【含斜三点】、四、五、六点)
一点 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>css flex布局-画骰子</title><sty…...
蓝桥集训之牛的学术圈 I
蓝桥集训之牛的学术圈 I 核心思想:二分 确定指数x后 判断当前c[i]是否>x(满足条件) 并记录次数同时记录 1后满足条件的个数最后取bns和m的最小值 为满足条件的元素个数ansbns为当前指数x下 满足条件的元素个数 #include <iostream>#include <cstring…...
软件设计师软考题目解析21 --每日五题
想说的话:要准备软考了。0.0,其实我是不想考的,但是吧,由于本人已经学完所有知识了,只是被学校的课程给锁在那里了,不然早找工作去了。寻思着反正也无聊,就考个证玩玩。 本人github地址…...
python读写json文件详解
在Python中,可以使用json模块来读写JSON格式的文件。下面是一个详细的示例,演示了如何读写JSON文件: import json# 写入JSON文件 data {"name": "John","age": 30,"city": "New York" }…...
#include<ros/ros.h>头文件报错
快捷键 ctrl shift B 调用编译,选择:catkin_make:build)(要先在vscode上添加扩展:ros) 可以点击配置设置为默认,修改.vscode/tasks.json 文件 修改.vscode/tasks.json 文件,否则ros.h头文件会报错 内容修改为以下内…...
mybatis单表curd笔记(尚硅谷
Mybatis 11111ibatis和mybatis不同 查询文档mybatis的日志输出id赋值输入(向sql语句传入数据单个简单类型单个实体对象多个简单类型map类型 输出数据的指定单个简单类型单个实体类型输出map类型输出list输出类型主键回显(自增长类型主键回显(…...
在线重定义-操作步骤
第一步:验证表是否能被在线重定义 验证是否能按主键重定义(默认,最后一次参数可以不加) 1 2 3 4 begin --dbms_redefinition.can_redef_table(scott,tb_cablecheck_equipment_bak); dbms_redefinition.can_redef_table(scot…...
16:00面试,16:06就出来了,问的问题过于变态了。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到2月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...
基于dashscope在线调用千问大模型
前言 dashscope是阿里云大模型服务平台——灵积提供的在线API组件。基于它,无需本地加载大模型,通过在线方式访问云端大模型来完成对话。 申请API key 老规矩:要想访问各家云端大模型,需要先申请API key。 对于阿里云&#x…...
【Python】可变数据类型 不可变数据类型 || hash
🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…...
MySQL 篇-深入了解多表设计、多表查询
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 多表设计概述 1.1 多表设计 - 一对多 1.2 多表设计 - 一对一 1.3 多表设计 - 多对多 2.0 多表查询概述 2.1 多表查询 - 内连接 2.2 多表查询 - 外连接 2.3 多表查…...
【Java】Spring的ReflectionUtils类常用方法学习笔记
目录 ReflectionUtils介绍 常用方法 访问字段 方法调用 处理回调 示例 脑容量不够了,以简单的小知识作为一天的结尾吧(悲 ReflectionUtils介绍 ReflectionUtils是Spring Framework中非常实用的一个工具类,为开发人员提供了简便的反射操作方法&am…...
内存函数详解
1. memcpy函数 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 函数的功能,使用与注意事项 1. memcpy函数的作用是内存拷贝,即将source指向的空间中的num个字节拷贝到destination指向的空间中去,然后返回de…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
