二分法可以作为某几类问题的通用解法:
1.有序序列中是否存在满足某条件的元素;
2.有序序列中第一个满足某条件的元素的位置;
3.有序序列中最后一个满足某条件的元素的位置。
1
查找一个严格递增序列中是否存在给定的数 x,存在返回下标序号,不存在返回 -1
int ef(int ow[], int left, int right, int x)
{
int mid;
while(left <= right)
{
mid = left + (right - left) / 2;
if(x == ow[mid])
return mid;
else if(x < ow[mid])
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
2
求出序列中第一个大于等于x的元素位置L,以及第一个大于x的元素位置R,x在序列中的存在区间就是 [L,R)。
查找一个非严格递增序列中,第一个大于等于x的元素位置
int lower_bound(int ow[], int left, int right, int x)
{
int mid;
while(left < right)
{
mid = left + (right - left) / 2;
if(ow[mid] >= x)
right = mid;
else
left = mid + 1;
}
return left;
}
查找一个非严格递增序列中,第一个大于x的元素位置
upper_bound
3
查找一个非严格递增序列中,最后一个小于x的元素位置
上述表述等价于“查找一个非严格递增序列中,第一个大于等于x的元素的前一个位置”
即先求第一个满足“!C"的元素位置,再将该位置 -1 即可。