【算法】二分查找

1、二分查找

在一个数组中寻找一个目标值,暴力解法就是遍历一遍数组,时间复杂度是O(N)

利用数组是升序的这个特点,可以在数组中随机找一个值,比较一下这个值与target的大小,若比target小,则这个值左边的全部数都比target小,比较一次就可以排除掉很多值,若这个值比target大也是同理。这就是利用了数组的二段性

二段性:当发现一个规律,根据这个规律,选取一个点,能把这个数组分成两部分,即根据规律能够有选择性的舍弃一部分,然后在另一部分中继续寻找,此时就可以用二分查找

实际上也不一定要是二分,三分、四分、五分等都是可以的,只要能将数组分成两部分然后排除掉一部分,只不过二分的时间复杂度是最好的

那按二分,时间复杂度是多少呢?

可以计算出x是log以2为底x的对数,所以时间复杂度是O(logN)

注意:算mid时,可能会发生溢出,所以可以采用先算出区间长度,再除2,然后让left加上前面运算的结果

class Solution {
public:
    // 左闭右闭
    int search(vector<int>& nums, int target) {
        int left = 0,right = nums.size() - 1;
        while(left <= right)
        {
            //int mid = (left + right) / 2;
            int mid = left + (right - left) / 2; // 防止溢出
            if(nums[mid] < target) left = mid + 1;
            else if(nums[mid] > target) right = mid - 1;
            else return mid;
        }
        return -1;
    }
};

朴素的二非模板

int search(vector<int>& nums, int target) {
    int left = 0,right = nums.size() - 1;
    while(...)
    {
        //int mid = (left + right) / 2;
        int mid = left + (right - left) / 2; // 防止溢出
        if(...) left = mid + 1;
        else if(...) right = mid - 1;
        else return ...;
    }
    return -1;
}

模板中的...是根据具体题目的二段性来填入,并且一定要是<=,因为[left,right]的区间内所有元素都是未知的

注意:mid的计算方式除了上面的两种写法,还有另外两种mid = (left + right + 1) / 2,

mid = left + (right - left + 1) / 2,这两种在奇数时与上面的没有区别,偶数时有,不过在朴素版本中是没有区别的,因为朴素版本只需要找到一个点来将数组划分为两个区域即可,这个点在那个位置均可,即使在1/3、1/4都可以

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值