代码随想录-二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:

makefile 复制代码
输入: nums = [-1,0,3,5,9,12], target = 9     
输出: 4       
解释: 9 出现在 nums 中并且下标为 4     

示例 2:

makefile 复制代码
输入: nums = [-1,0,3,5,9,12], target = 2     
输出: -1        
解释: 2 不存在 nums 中因此返回 -1        

提示:

  • 你可以假设 nums 中的所有元素是不重复的。
  • n 将在 [1, 10000]之间。
  • nums 的每个元素都将在 [-9999, 9999]之间

二分查找使用场景

数量固定的有序数组,且数组元素无重复。 数组元素重复,查找出来的下标可能不是唯一的。

重点

二分查找某个元素,一次查找为查询到需要重复查找每个二分区间,需要重复,因此使用while。 要比较中间元素与目标元素,因此需要有三个变量,left,right,mid,分别用于计算当前循环的mid值,改变当前查找的目标区间。 停止查找有两种情况:

  1. 查询到目标元素
  2. 数组所有元素查找完但是未找到目标元素,当left值大于或者等于right时,表示数组无可查找的元素了,就结束查找,返回return表示未找到元素下标。

left和right代表数组最左侧和右侧元素的下标,left初始化为0,right初始化分为两种情况:

  1. right初始化为数组length-1,即numbers[right]为数组中可取值,数组目标元素的查找区间为[left,right],只要保证left<=right,就可以继续查找(left == right时数组元素存在)
  2. right初始化为数组length, number[right]该值不存在,所以数组的目标查询区间为[left,right),所以需要保证left<right时才能继续查找

right - left表示 当前搜索区间的长度

(right - left) >> 1表示right - left 的值 右移一位,等价于除以 2(向下取整)

mid = left + ((right - left) >> 1)最终的中间值索引,等价于:mid = left + (right - left) / 2;

sql 复制代码
```js
情况1:[left,right)
function search(numbers,target){
    let left,mid = 0;
    let right = numbers.length
    // 数组不包括下标为right的元素
    while(left < right){
        mid = left + ((right - left)>>2)
        // 查询到目标值,返回下标,退出循环
        if(numbers[mid] == target){
            return mid
        // 中间值大于目标值,则目标应该在左区间,修改查询区间为左区间
        }else if(numbers[mid] > target){
            // 区间不包括right,目标值下标不可能为mid,因此将mid赋值给right
            right = mid
        }else{
            // 中间值小于目标值,目标值在右区间,修改查询区间为右区间
            // 已知中间值不是目标值,则右查询区间不包括mid,因此left赋值为mid+1
            left = mid + 1
        }
    }
    // 查询遍所有元素都不包括目标值,return-1
    return -1;
}
js 复制代码
情况2:[left,right]
function search(numbers,target){
    let left,mid = 0;
    let right = nummbers.length - 1; // right为数组中最后一个元素的下标,存在
    while(left <= right){
        mid = left + ((right - left)>>2)
        if(numbers[mid] == target){
            return mid
        }else if(numbers[mid] > target){
            right = mid -1
        }else{
            left = mid + 1
        }
    }
    return -1
}
相关推荐
人工智能训练1 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪1 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9222 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233223 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88214 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1364 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
A_nanda4 小时前
c# MOdbus rto读写串口,如何不相互影响
算法·c#·多线程
摇滚侠4 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
2601_949833395 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
珑墨5 小时前
【Turbo】使用介绍
前端