双指针算法,可以优化一些朴素算法,减少遍历的次数 ,降低算法的时间复杂度。
一般模板
1 2 3 4 5 6
| for (int i = 0, j = 0; i < n; i ++ ) { while (j < i && check(i, j)) j ++ ;
}
|
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <iostream>
using namespace std;
const int N = 100010;
int n; int a[N], s[N];
int main() { cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; int res = 0; for (int i = 0, j = 0; i < n; i++) { s[a[i]]++; while (s[a[i]] > 1) { s[a[j]]--; j++; }
res = max(res, i - j + 1); } cout << res << endl; return 0; }
|
给定两个升序排序的有序数组 A 和 B,以及一个目标值 x。
数组下标从 0 开始。
请你求出满足 A[i] + B[j] = x
A[i]+B[j]= x
的数对 (i,j)(i,j)
。
数据保证有唯一解。
求目标和的时候双指针一个指向首位,一个指向末尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream>
using namespace std;
const int N = 100010;
int A[N], B[N]; int n, m, x;
int main() { cin >> n >> m >> x; for (int i = 0; i < n; i++) cin >> A[i]; for (int i = 0; i < m; i++) cin >> B[i]; for (int i = 0, j = m - 1; i < n; i++) { while (j >= 0 && A[i] + B[j] > x) j--; if (A[i] + B[j] == x) { printf("%d %d", i, j); break; } } return 0; }
|