一、二分查找
二分查找很常见了,放一个模板就溜。
时间复杂度 O(logn),log以2为底。
(最后得到的是可行域的闭区间 [l,r] )
while(r>l)
{
mid=(l+r+1)/2; //注意是l+r+1
if(check(mid)==true) l=mid;
else r=mid-1;
}
二、三分查找
三分查找用于查找一个凸(凹)函数的极值点。
时间复杂度 O(2*logn),log以3为底。
对于一个区间[l,r],先取中点mid=(l+r)/2,再取[mid,r]的中点mid2=(mid+r)/2;
然后比较f(mid)与f(mid2);
若f(mid) > f(mid2):r=mid2;
若f(mid) < f(mid2):l=mid;
正确性证明:
①若f(mid) > f(mid2),则极值点x在mid2左侧。
反证:若x在mid2右侧,则mid与mid2均在x左侧,由单调性得f(mid) < f(mid2),矛盾;
②若f(mid) < f(mid2),则极值点x在mid右侧。
反证:若x在mid左侧,则mid与mid2均在x右侧,由单调性得f(mid) > f(mid2),矛盾;
三分模板:
①while(l<r-1)
{
mid=(l+r)/2;
mid2=(mid+r)/2;
if(f(mid)>f(mid2)) r=mid2;
else l=mid;
}
if(f(l)>f(r)) return l;
else return r;
②while(l<r)
{
mid=(l+r)/2;
mid2=(mid+r+1)/2;
if(f(mid)>f(mid2)) r=mid2-1;
else l=mid+1;
}
return l;