二分法是一种常见的搜索算法。在一个长度为n的数组当中查找一个数,使用暴力查找法时间复杂度为O(n),如果使用二分搜索法,复杂度则为O(logn)。
例如,在四数之和问题当中,使用暴力法,枚举部分的代码如下
for(int a = 0;a<n;a++){
for(int b = 0;b<n;b++){
for(int c = 0;c<n;c++){
if(int d = 0;d<n;d++){
if(k[a]+k[b]+k[c]+k[d]==m){
f = true;
}
}
}
}
}
想要实现二分法对这个搜索程序进行改进,可以修改最内一层的循环。此时时间复杂度为O(n^3logn)
if(binary_search(m - k[a] - k[b] - k[c])){
f = true;
}
还可以修改最内两层的循环,使得程序的时间复杂度进一步减小到O(n^2logn)。
内侧的循环是检查kc+kd = m-ka-kb,需要将kc+kd作为一个整体先进行排序。这部分共有n^2种可能,确切的说,去掉重复后只有n(n+1)/2个数字
void solve(){
//枚举kc+kd,得到n^2个数字
for(int c = 0;c < n;c++){
for(int d= 0;d<n;d++){
kk[c*n+d] = k[c]+k[d];
}
}
//排序
sort(kk,kk+n*n);
bool f = false;
for(int a = 0;a<n;a++){
for(int b = 0;b<n;b++){
if(binary_search(m-k[a]-k[b])){
f = true;
}
}
}
}
关于STL当中二分查找相关函数,可以看这篇文章http://t.csdn.cn/V8kjs