双指针
双指针
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) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作。
②注意边界情况。