二分查找算法

简介

二分法是一种基于有序序列的查找算法,时间复杂度是O(logn)。

二分区间

查找的时候首先要确定区间的类型,主要可以分为两种,左闭右闭[,]和左闭右开[,)(左开右闭同理)。区间的不同意味着边界的判断条件不同:缩小区间时候是取mid还是取mid-1,以及区间的合法性不同:左闭右闭left是可以等于right的,循环条件是while(left<=right),例:[1,1]合法,而左闭右开区间,如果相等[1,1)则是不合法的。

1.左闭右闭区间[left,right]:

int search(int* nums, int n, int target)
{
    int left = 0;
    int right = n-1;
    int mid = 0;
    while(left<=right) {
        mid = (left+right)/2;
        if(nums[mid] > target) {
            right = mid-1;
        } 
        else if(nums[mid] < target) {
            left = mid+1;
        } 
        else if(nums[mid] == target){
            return mid;
        }
    }
    return -1;
}

2.左闭右开区间[left,right)

int search(int* nums, int n, int target)
{
    int left = 0;
    int right = n;
    int mid = 0;
    while(left < right){ 
        int mid = left + (right - left) / 2;
        if(nums[mid] < target){
            left = mid + 1;
        }else if(nums[mid] > target){
            right = mid ;
        }else{
            return mid;
        }
    }
    return -1;
}

注意

  • 有序序列中不能有重复元素,否则二分查找的返回值不唯一;
  • 左闭右开区间右边界取的是n不是n-1;
  • mid = (left+right)/2;这句如果数组较大,上界超出了int型数据范围的一半,在查找到数组的后半段的时候可能溢出,可以用int mid = left + (right - left) / 2;来代替避免溢出;
  • 如果题目问的是目标值在不在区间里面,可以用左闭右闭区间查找,找到了就返回目标值下标或者输出,没找到就返回-1;如果题目问的是找到第一个大于/小于目标值的下标,就用左闭右开区间,判断小于等于和大于,循环结束时的右边界就是第一个大于目标值的下标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值