双指针

双指针

双指针

1、用途

在序列满足一定单调性的情况下线性时间寻找可行解

2、原理

51Nod 1001为例。

首先对序列排序。假设目前已经找到\(a[i]+a[j]=k(i<j)\),那么当\(i\)变为\(i+1\)时一定有\(a[i+1]>a[i]\)。设当前下标取到\(p\)时有\(a[i+1]+a[p]=k\),所以\(a[i+1]+a[p]=a[i]+a[j]\),即\(a[i+1]-a[i]=a[j]-a[p]>0\)。由\(a[i]\)单调递增,得\(j>p\)。所以当\(i\)不断往后遍历时,\(j\)一定只会向前移动。于是采取头尾指针,不断更新即可。

由于每个指针最多只会线性时间遍历一遍数组,总复杂度为\(O(n)\)

3、模板

for (int i = 1, j = init; vaild(i, j); ++i)
{
    while (vaild(i, j) && check(i, j)) opt(j);
    // operations
}

4、复杂度

\(O(n)\)

5、备注

①常见问题:(1) 对于一个序列,用两个指针维护一段区间;(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作。

②注意边界情况。

例题

AcWing 799 最长连续不重复子序列

Gym 291271D 等和数对1

posted @ 2020-08-28 11:46  Lecxcy  阅读(83)  评论(0)    收藏  举报