二分查找边界控制

二分查找边界控制

前言

本文主要研究二分查找左右边界控制,不同的查找目的,边界控制会略有不同。以下都采用左闭右闭区间,仅在第一个示例中演示左闭右开区间。

二分的本质实际上是区间,即两段性,非此即彼。
在这里插入图片描述

查找某个特定值

// 左闭右闭
int binarySearch(int arr[],int n,int key){
	int low=0,high=n-1,mid;	// 左闭右闭,注意high=n-1
   	while(low<=high){
       mid=low+((high-low)>>1);	// 防溢出
	    if(key==arr[mid]){
            return mid;
        } else if(key<arr[mid]){
            high=mid-1;
        } else {
			low=mid+1;
        }
	}
    return -1;
}
// 左闭右开
int binarySearch(int arr[],int n,int key){
	int low=0,high=n,mid;	// 左闭右开,注意high=n
   	while(low<=high){
       mid=low+((high-low)>>1);	// 防溢出
	    if(key==arr[mid]){
            return mid;
        } else if(key<arr[mid]){
            high=mid;
        } else {
			low=mid+1;
        }
	}
    return -1;
}

查找第一个大于等于某个数的下标

// 终止前一步为: low=high,得mid = low,此时如果key <= a[mid],则high会改变,而low指向当前元素,即为满足要求的元素。如果key > a[mid],则low会改变,而low指向mid下一个元素。
int binarySearch(int arr[], int n, int key) {
	int low = 0, high = n - 1, mid;	// 左闭右闭
	while (low <= high) {
		mid = low + ((high - low) >> 1);	// 防溢出
		if (key <= arr[mid]) {	// <=
			high = mid - 1;
		} else {
			low = mid + 1;
		}
	}
	return low<=n?low:-1;
}

查找第一个大于某个数的下标

int binarySearch(int arr[], int n, int key) {
	int low = 0, high = n - 1, mid;	// 左闭右闭
	while (low <= high) {
		mid = low + ((high - low) >> 1);	// 防溢出
		if (key < arr[mid]) {	// <
			high = mid - 1;
		} else {
			low = mid + 1;
		}
	}
	return low<=n?low:-1;
}

二分模板

当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

这两个模板与上面的两个原理都一样,各有所爱即可。

扩展

(1) 查找数组中某个数的位置的最小下标

可以先查找数组中第一个大于等于某个数的位置,然后做一个判断,如果等于这个数直接返回下标,否则就返回-1

(2) 查找数组中某个数的位置的最大下标

可以先查找数组中第一个大于这个数的位置,然后将这个数和这个位置上的前一数进行比较,如果相等返回前一个位置,否则就返回-1。

(3) 查找数组中小于某个数的最大下标

可以先查找第一个大于等于这个数的下标,如果前一个位置有效,返回前一个位置,否则返回-1

(4) 查找数组中某个数的出现次数

首先用(1)求下界,然后用(2) 求上界,如果上界和下界都存在二者的差值+1就是出现的次数

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值