双指针/滑动窗口 优化 二分区间
作者:互联网
二分区间:
FOR(i, 1, n, 1){
int lef = 根据i来二分;
int rig = 根据i来二分;
}
他的时间是: O(n * logN)。
如果说,每一次的{lef, rig}
,满足某种单调性
即:{lef[1], rig[1]} {lef[2], rig[2]} {lef[3], rig[3]} .....
他们满足某种单调性
可以考虑用:双指针/滑动窗口,优化成O(n)
有n个一维的 递增的 点A, 有m个一维的 递增的 人B,有一个len距离,表示: 一个人可以覆盖 左右[-len, len]的点。
问,这些人 是否可以覆盖所有点。
动态维护一个rig,表示: 前i个人,已经覆盖了A[1, 2, 3..., rig]
这些点。
当前遍历的第i+1
个人,根据{ B[i+1] - m, B[i+1] + m }
范围 获取[l] [r]
,表示:A[l, l+1, .., r]
这些点 是处于这个范围的。
if( l <= rig ) MAX(rig, r);
这是二分的做法,每次二分获取一个[l, r]
,然后用这个区间 尝试更新rig。
B是单调的,每次得到的[l] [r]
,也是单调的。
因此,其实不需要二分得到[l] [r]。 直接每次尝试让rig增长即可。
bool check( int len ){
int pre_rig = 0;
FOR(i, 1, m, 1){
LL lef = (LL)B[i] - len, rig = (LL)B[i] + len;
while( pre_rig + 1 <= n ){
if( A[pre_rig + 1] >= lef && A[pre_rig + 1] <= rig ){
++ pre_rig;
}
else{
break;
}
}
if( pre_rig == n )
return true;
}
return pre_rig == n;
}
标签:二分,pre,lef,int,len,rig,滑动,指针 来源: https://blog.csdn.net/weixin_42712593/article/details/120400327