基础算法——二分查找

1、简要概述

因为按元素排列顺序在数组中查找元素效率太低了,每次都要从头到尾去遍历元素。对此聪明的科学家研究出了二分查找算法,一种更高效的查询方法。

使用前提:数组中无重复的元素并且数组是有序的。

算法逻辑:定义两个首尾指针,及其中点元素,每次将中点值与目标值进行比对,比目标值小右指针收缩,比目标值大左指针收缩,不断重复直到找到目标值或者首尾指针重叠越界。

其逻辑类似与排除法,将不必要的元素排除在外,只搜寻目标区间内的元素,省去了很多不必要的检测,从而极大的提高了查找效率

2、例题实战

力扣:704题 . - 力扣(LeetCode)

实现代码:

class Solution {
    public int search(int[] nums, int target) {
​
        //定义首尾指针
        int l = 0;
        int r = nums.length - 1;
        
        //确定查找区间
        while(l <= r){
            //中点元素
            int mid = l + r >> 1;
            //缩小寻找范围
            if(nums[mid] < target) l = mid + 1;
            else if(target < nums[mid]) r = mid - 1;
            else return mid;
        }
​
        return -1;
    }
}

代码逻辑:

在区间 [l,r]中查找目标元素

目标值比中间值小,缩小区间为 [l,mid - 1] (因为mid处的值肯定不是目标值,因此下一次搜索的地方在mid - 1后)

目标值比中间值大,缩小区间为 [mid + 1, r]

例题2:力扣35题 . - 力扣(LeetCode)

class Solution {
    // public int searchInsert(int[] nums, int target) {
    //     int l = 0;
    //     int r = nums.length;
​
    //     while(l < r){
​
    //         int mid = l + r >> 1;
​
    //         if(nums[mid] == target) return mid;
    //         else if(nums[mid] < target) l = mid + 1;
    //         else r = mid;
    //     }
​
    //     return l;
    // }
​
    public int searchInsert(int[] nums, int target) {
​
        int l = 0, r = nums.length - 1;
​
        while(l <= r){
​
            int mid = l + r >> 1;
​
            if(nums[mid] == target) return mid;
            else if(nums[mid] < target) l = mid + 1;
            else r = mid - 1;
        }
​
        return l;
​
​
    }
}

注释部分逻辑:

搜索区间[l,r), 注意此次搜索区间不包括右端点,所有初始赋值时r = nums.length

当目标值比中点值小时,缩小右区间,r = mid

为什么这次不是,r = mid - 1 呢?

原因,要搜索的区间是[l , r ) 右边界不包括r处,当右边界需要缩小时,此时mid处已经被判断过了,不会是目标点

而mid - 1我们无法确定,所有我们让 r = mid

如果让 r = mid - 1,区间就会变成[l, r]

3、自我挑战

力扣1044题:. - 力扣(LeetCode)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值