【算法学习随笔】二分查找法

二分查找法

二分查找的本质就是分治法,小时候由过这么一种猜数字的游戏,你在心中想一个大于0小于100的数字,然后我来提问,你只用回答是或者不是,比如“你想的数字比50大吗” 你说不是,那么就将范围缩小到0-50,反之范围就在50-100;
就这样逐步询问,最终总能猜到你心里想的数字,并且每次都以范围一半的值作为提问的参考值的话,你相对提问的次数是最少的,也就是提问的最优解;这就是二分法

二分查找发的基本思想

将n个元素分成大致相等的两部分,取a[n/2] ( a[]是数组,n/2是数组索引)与目标元素target作比较

  • 如果target = a[n/2],那这就是要找的元素
  • 如果target < a[n/2],继续搜索,搜索范围缩小到数组a的左半部分
  • 如果target > a[a/2],继续搜索,搜索范围缩小到数组a的右半部分

二分查找的时间复杂度

  • 因为循环时一层,所以有n个元素时间复杂度就是循环的次数k,n=>n/2=>n/4...=>n/2^k。
  • n足够大的时候极限n/2^k趋近与1
  • k = log2n
  • 时间复杂度为O(n) = O(log2n) 或者O(n) = O(logn)

实现

class Solution{
public:
int search (vecter<int>& nums,int target){
int left = 0;
int right = nums.size() - 1;

while (left <= right){
int mid = left + (right-left)/2;
if(nums[mid] == target){
return mid;
}
else if(nums[mid] > target){
right = mid -1;
}
else if(nums[mid] < target){
left = mid -1;
}
}
return -1;
}
}
  • 这里有几个细节
  • 循环的终止条件用的是小于等于 while (left <= right),因为只是小于的时候回漏掉等于的情况就是[2,2]这种情况回终止循环返回-1;
  • 还有就是在计算这个
int mid = left + (right-left)/2;

的时候 我们可以用left + ((right -left) >> 1 位运算提升性能;

posted @ 2021-12-24 00:17  CeliaChu207  阅读(41)  评论(0编辑  收藏  举报