双指针
1. 简介
通常用于数组或字符串中进行快速查找、匹配、排序或移动操作
常见的双指针模型:
- 对撞指针
- 快慢指针
2. 对撞指针
指的是两个指针 left、right (简写为l,r) 分别指向序列第一个元素和最后一个元素。然后1指针不断递增,r不断递减,直到两个指针的值相撞或错开 (即 l >= r),或者满足其他要求的特殊条件为止。
对撞指针一般用来解决有序数组或者字符串问题 (常见于区间问题)
查找有序数组中满足某些约束条件的一组元素问题:比如二分查找、数字之和等问题
字符串反转问题:反转字符串、回文数、颠倒二进制等问题。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
char s[N];
int main()
{
cin >> s + 1;
int n = strlen(s + 1);
int l = 1, r = n;
bool ans = true;
while(l < r)
{
if(s[l] != s[r]) ans = false;
l ++ , r -- ;
}
cout << (ans ? "Y" : "N");
}
3. 快慢指针
快指针为r,慢指针为1,这样慢指针和快指针构成区间[l, r]
两个指针以不同速度、不同策略移动,直到快指针移动到数组尾端,或者两指针相交,或者满足其他特殊条件时为止。
初始状态,l
一般指向a[1]
,r
一般指向a[0]
,此时[1, 0]
表示空区间
出循环条件:l == n 或 r == n
,或者两指针相交
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int main()
{
int n, S; cin >> n >> S;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
// ans 初始取 n + 1(不可能取到)
int ans = n + 1;
// j:快指针,i:慢指针
for(int i = 1, j = 0, sum = 0; i <= n; i ++ )
{
// 若为不合法区间(i > j)或 j 有右移空间且还未达到 S : j 右移
while(i > j || (j + 1 <= n && sum < S)) sum += a[ ++ j];
// 此时区间一定合法
if(sum >= S) ans = min(ans, j - i + 1);
sum -= a[i];
}
cout << (ans > n ? 0 : ans) << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main()
{
int n, m, k;
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
int ans = 0;
for(int i = 1, j = 0, cnt = 0; i <= n; i ++ )
{
while(i > j || (j + 1 <= n && cnt < k)) cnt += (a[ ++ j] >= m);
if(cnt >= k) ans += n - j + 1;
cnt -= (a[i] >= m);
}
cout << ans << endl;
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。