1、算法思想

二分查找的思想很简单。假设有一个非降序的数据集合。先找出集合中最中间的那个元素,将数据集分割成两个子集。将最中间的元素和关键字key比较,如果等于key就返回,如果大于key,就证明key在前一个子集中,否则就在后一个子集查找,直到找到key返回。若没有找到返回-1。

二分查找只适用于有序数据集合,所以看到题中出现非降序、有序等字眼要想到二分查找。

2、代码实现

//区间[l.r]被划分成[l,mid]和[mid+1,r]时使用
int bsearch_1(int l.int r)
{
  while(l<r)
  {
    	int mid = l+r>>1; //右移一位代表(l+r)/2
    	if(check(mid)) r = mid; //check(mid)是判断mid是否满足 性质
    	else l = mid +1;
  }
  return l;
  
}
//区间[l.r]被划分成[l,mid-1]和[mid,r]时使用    
int bsearch_2(int l.int r)
{
	while(l<r)
	{
		int mid = l+r+1>>1;//不加1的话可能会出现死循环,比如l=r-1的情况
		if(check(mid)) l = mid;
		else r= mid-1;
	}
	return l;
}

上述两个模板使用那个要看题中如何分区间。比如给定一个题,首先写个check函数,来判断一下如果满足条件应该划到那个区间中。 **

常用模板

    int search(vector<int>& nums, int target) {
        if(nums.empty()) return -1;
        int l = 0;
        int r = nums.size()-1;
        while(l<=r)
        {    
            int mid = l+r>>1;
            if(target==nums[mid]) return mid;
            else if(target>nums[mid]) l = mid+1;
            else r = mid-1;
        }
        return -1;
    }

3、总结

二分查找的思想虽然极其简单,但是一定要注意边界问题,否则会出现查找失败、死循环等情况。