二分查找都很熟悉了,对于有序的数组来说,对齐进行处理基本都是二分查找。
下面来看几个应用:
1、N+1个数,放在长度为N的数组里面且元素有序,元素从0-N+1,且没有重复,求出缺少哪一个元素。例如:array【10】 = {0,1,2,3,5,6,7,8,9,10}
利用二分查找思路:如果元素与其索引相等,那么继续向后寻找(即low = mid + 1),如果元素与其索引不相等那么向前找(即,high = low - 1),最后返回low。
int findOmit(int *array, int len)
{
int low = 0;
int high = len - 1;
int mid = 0;
while (low <= high) {
mid = (low + high)/2;
if (array[mid] == mid)
low =mid + 1;
else
high = mid - 1;
}
return low;
}
2、N个数放入长度为N+1的数组中,数组有序,只有一个重复元素,找出那个重复元素。例如:array【10】 = {0,1,2,3,3,4,5,6,7,8}
利用二分查找思路:如果元素与其索引相等,那么继续向后寻找(即low = mid + 1),如果元素与其索引不相等那么向前找(即,high = low - 1),最后返回low-1。
int findDup(int *array, int len)
{
//找重复元素
int low = 0;
int high = len - 1;
int mid = 0;
while (low <= high ) {
mid = (low + high)/2;
if ( array[mid] == mid) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return low - 1 ;
}
3、在有序数组中求大于数X的第一个数。
思路差不多,直接上代码:
int findFMax(int *array, int len, int key)
{
int low = 0;
int high = len - 1;
int mid = 0;
while (low <= high) {
mid = (low + high)/2;
if (key < array[mid])
high = mid - 1;
else
low = mid + 1;
}
return low;
}
4、在有序数组中求小于X的第一个数。
int findFMin(int *array, int len, int key)
{
int low = 0;
int high = len - 1;
int mid = 0;
while (low <= high) {
mid = (low + high)/2;
if (array[mid] < key)
low = mid + 1;
else
high = mid - 1;
}
return low - 1;
}
5、求一个有序数组中,元素X出现的次数。
利用3、4的组合即可求出。
int Count(int *array, int len, int key)
{
int low = findFMin(array, len, key);
int high = findFMax(array, len, key);
return high - low - 1;
}
其实,可以看出在有序数组中利用二分查找解决问题时,思路是差不多的,low、mid、high,看你怎么样设置low,与high变化的条件,解决能不能作对,要看你对与查找结束后,low与high位置的把我。上面1、2、3、4,看看你能不能彻底理解为什么有的返回low,有的返回low-1。