在序列满足一定单调性的情况下线性时间寻找可行解
以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)\)。
for (int i = 1, j = init; vaild(i, j); ++i)
{
while (vaild(i, j) && check(i, j)) opt(j);
// operations
}
\(O(n)\)
①常见问题:(1) 对于一个序列,用两个指针维护一段区间;(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作。
②注意边界情况。
原文:https://www.cnblogs.com/Lecxcy/p/13576584.html