学术计划VOL.2 双指针!
2025-10-12 20:30:41
发布于:重庆
双指针!
前言:
这是Stars_Seeker推出的学术计划系列的第二期,希望这个系列能够帮助到刚学习 C++ 或者复习 C++ 却不知道复习哪些的同学们,同时这个系列没有过多的言语和绝美的佳句
作者语文不好(,只有透彻又不完全透彻的知识awa。
写的这么差的帖子肯定是AI(
双指针是什么
双指针可以看做对于枚举的一种优化。
对于两个指针如果分别从 1 到 n 枚举,那么两重循环嵌套,复杂度是 O(n^2),
但在一些具有单调性的题目中,可以使 i 指针和 j 指针都只需要从 1 到 n 遍历一次,复杂度分别为 O(n) , 总复杂度也是 O(n) 。
例题 1: P1147 连续自然数和
思路:构建前缀和数组,由于数字都大于 0,那么前缀和数组存在单调性,可以考虑双指针 i 指针移动时候,为了使得区间和仍然接近 n,j 指针只会向右移动,因此 i 指针和 j 指针都只需要从 1 到 n 遍历一次, 复杂度分别为 O(n) , 总复杂度也是 O(n) 。
代码实现
#include<bits/stdc++.h>
using namespace std;
long long n,s[1145141];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
s[i]=s[i-1]+i; //递推构建前缀和数组
}
for(int i=1,j=1;i<=n;i++){ //i每次往右移动一格
while(j+1<=n&&s[j+1]-s[i-1]<=n){//找到符合条件的最大的j
j++;
}
//条件为 [i, j] 的区间和小于等于n
if(j<=i){
break; //因为需要最少两个数字 所以 j <= i事后可以直接break
}
if(s[j]-s[i-1]==n){
cout<<i<<" "<<j<<endl; //检查符合条件那么输出
}
}
//完美的结束(
}
例题 2: P1102 A-B 数对
思路: 先排序使得数组存在单调性, 然后 i 指针从 1 到 n 扫一遍,复杂度为 O(n) , 每次找到符合条件的最大的 j ,将对应的数量加入答案,为了了解当前的 j 是同类数字里出现的第几个数字,可以另外开一个 cnt 数组来记录。为了保持 j 指针尽量大并且满足 a[i] - a[j] >= c ,当 i 指针向右移动时候, j 指针只会不变或者向右移动,那么 j 指针的总移动次数也是 O(n) 。
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,a[114514],cnt[1145141];
int main(){
int c;
cin>>n>>c;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n); //创造单调性
for(int i=1;i<=n;i++){
cnt[i]=1;
if(a[i]==a[i-1]&&i>1){//记录出现的是第几个
cnt[i]=cnt[i-1]+1;
}
}
long long ans=0; //可能会爆 int
for(int i=1,j=1;i<=n;i++){
while(j<i&&a[i]-a[j+1]>=c){
j++; //保证j的位置小于等于 i,寻找符合条件的j的最大值
}
//想要的条件是 a[i] - a[j] >= c,在此基础上 j越大,越接近c
if(a[i]-a[j]==c){
ans+=cnt[j]; //刚好是c就加入到答案里
}
}
cout<<ans<<endl;
//完美的结束*2(
}
是的没错,你没有听错,第二期结束了!
比第一期稍微长了一点,因为加了2道例题。以后字数不够的时候凑字数就这么写 )))
本篇文章中“代码的注释”部分内容是作者它询问了它的教练,所以会看起来很权威。
如果文章中出现质量问题或者还有其他思路,欢迎在评论区讨论
<-上一篇学术计划
全部评论 19
没人看吗
昨天 来自 重庆
2d
5小时前 来自 重庆
16
5小时前 来自 重庆
1bushigemen你不上课吗
5小时前 来自 重庆
06,你不上课吗
5小时前 来自 重庆
0
d
5小时前 来自 重庆
15小时前 来自 重庆
0
昨天 来自 重庆
1又犯啥错了
昨天 来自 浙江
0把我开户了
昨天 来自 上海
0
MC团队招人拉!想在电脑上玩MC,可以进来我们团,里面的作业里有(https://www.acgo.cn/application/1913576045675352064)
14分钟前 来自 广东
0dd
5小时前 来自 重庆
0d
5小时前 来自 重庆
0d
5小时前 来自 重庆
0d
5小时前 来自 重庆
0d
5小时前 来自 重庆
0d
5小时前 来自 重庆
0顶
19小时前 来自 山东
0话又说来说,嫩头像咋这么多嘞
21小时前 来自 广东
021小时前 来自 重庆
0哈哈哈我在摸ppl (
21小时前 来自 重庆
0
中啊
21小时前 来自 广东
021小时前 来自 重庆
0
ddd
昨天 来自 浙江
0ddd
昨天 来自 浙江
0dd
昨天 来自 浙江
0《114514》
昨天 来自 浙江
0昨天 来自 重庆
0可以点个赞吗谢谢啦
昨天 来自 重庆
0🆗
昨天 来自 浙江
0
那啥
昨天 来自 浙江
0
有帮助,赞一个