前言
本文主要叙述一下什么叫二分查找,以及二分查找使用的场景
二分查找介绍
二分查找最最常见的就是在有序数组中查找某一个数的位置,具体操作就是用每次用中间元素和所需的数比较,如果在左边就取左部分,右边就取右部分!然后再去部分中间元素比较,直到找到为止!
代码展示
具体代码:
int Binary_search(int arr[], int len,int k)
{
int left = 0;
int right = len - 1;
int mid = ((right - left)/2 + left);//相当于(left+right)/2,防治越界, 可以这样写mid = ((right - left)>>1) + left;
while (left <= right)
{
if (k ==arr[mid])
return mid+1;
if (k < arr[mid])
{
right = mid-1 ;
mid = ((right - left)/2 + left);
}
else
{
left = mid +1;
mid = ((right - left)/2 + left);
}
}
}
面试题考法
1.在一个有序数组中,找>=某个数最左侧的位置或者在一个有序数组中,找<=某个数最右侧的位置
思路:一直查找,如果找到就记录下标,然后继续查找,直到结束
至于左还是右,就处理一下细节,下面的代码用过<=来优化,因为想找最左侧位置,那么我们得找到左区域,于是就用了<=,因为我们已经找到了相等的第一个下标,所以往下取区域的时候因为=号,直接进入左区域
int Binary_search(int arr[], int len, int k)
{
int left = 0;
int right = len - 1;
int mid = ((right - left) >> 1) + left;
int t = 0;
while (left <= right)
{
if (k == arr[mid])
t = mid + 1;
if (k <arr[mid])//取左区域
//查找最左边就用<=,最右边就用<
{
right = mid - 1;
mid = ((right - left) >> 1) + left;
}
else//取右区域
{
left = mid + 1;
mid = ((right - left) >> 1) + left;
}
}
return t;
}
2.存在局部最小值问题
题目是:在一个无序数组中有正有负,但是任意两个相邻数一定不相等,找到一个就结束
分析:(罗尔定理) 这个题目可以简化为说只要数组不是单调的,且只要有局部先减后升的,就一定存在!所以我们只需判断局部增减区间即可!!
看代码:
int Binary_search(int arr[], int len)
{
int left = 0;
int right = len - 1;
int mid = ((right - left) >> 1) + left;
while (left <= right)
{
if (arr[mid]<arr[mid-1]&&arr[mid]<arr[mid+1])
return mid + 1;
if (arr[mid] > arr[mid + 1])//减区间,取右区域
{
left = mid + 1;
mid = ((right - left) >> 1) + left;
}
else if (arr[mid] < arr[mid - 1])//增区间,取左区域
{
right = mid - 1;
mid = ((right - left) >> 1) + left;
}
}
}
这里我们看到二分查找不一定只适用于有序数组,在一些特定条件下无序数组也是可以成立的,思维的懂得变通,可别古板哦!!