二分法
能用二分法处理的问题都有一个共同特征即题目具有单调性。
二分法的题目类型如下:
1. 基本二分:对有序数组进行查询
2. 查找下届:有序数组中如果要查找的数存在则返回第一次出现的位置,否则返回比该数大的第一个数的位置,STL的lower_bound实现了此功能。
1) SGI STL源码:
int* LowerBound(int* first,int* end,int num)
{
int mid,size = end - first;
while( size > 0 )
{
mid = size >> 1;
if(*(first + mid) < num)
{
first += (mid + 1);
size -= (mid + 1);
}
else
{
size = mid;
}
}
return(first);
}
此版本代码最经典,但是理解很困难
2) 我实现版本:
int LowerBound(int a[],int n,int key)
{
//特判key大于a中所有数的特殊情况
if(key > a[n - 1])
{
return(n);
}
int s,e,mid;
s = 0;
e = n - 1;
while(e - s > 1)
{
mid = (s + e) >> 1;
if(a[mid] < key)
{
s = mid + 1;
}
else
{
e = mid;
}
}
if(a[s] >= key)
{
return(s);
}
return(e);
}
3. 查找上届:和查找下届类似