【js刷题:数据结构数组篇之二分查找】

二分查找

  • 一、什么是二分查找法
  • 二、具体实现步骤
    • 1.确定确定target所在数组的**左右边界**
      • 左闭右闭
      • 左闭右开
    • 2.取中间值
      • 左闭右闭
      • 左闭右开
    • 3.中间元素=目标值
    • 4.中间元素大于目标值
    • 5.中间元素小于目标值
    • 6.重复
  • 三、使用条件
  • 四、js版本示例
    • 1.左闭右闭
    • 2.左闭右开
  • 五、力扣刷题
    • 1.搜索插入位置

一、什么是二分查找法

二分查找法(Binary Search)是一种在有序数组中查找特定元素的算法。它通过将目标值与数组中间元素进行比较,从而排除掉一半的数据,以实现快速的搜索过程。

二、具体实现步骤

1.确定确定target所在数组的左右边界

写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)

左闭右闭

如果我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right]
那么遍历时的范围就应该是while (left <= right), 要使用 <= ,因为left == right是有意义

左闭右开

如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right)
那么遍历时的范围就应该是while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义

2.取中间值

取数组的中间元素,与目标值进行比较。

左闭右闭

如果我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right]。假如说target的值小于数组中间的那个数,也就是if (nums[middle] > target) ,target在数组的左半部分,那么right 要赋值为 middle - 1,因为target肯定比原本的middle值要小,我们不需要再去比较一次i原本middle和target的值了,并且我们是定义的一个闭区间,所以right要赋值给middle-1,也就是说下次我们在[0,middle-1]这个闭区间里面继续找。

左闭右开

如果说定义 target 是在一个在左闭右开的区间里,假如说target的值还是小于数组中间的那个数,也就是if (nums[middle] > target) ,target在数组的左半部分,那么right 要赋值为 middle,因为target肯定比原本的middle值要小,我们也不需要再去比较一次i原本middle和target的值了,并且我们是定义的一个开区间,所以下次我们就在[0,middle)这个区间找。

3.中间元素=目标值

如果中间元素等于目标值,则找到了目标,算法结束。

4.中间元素大于目标值

如果中间元素大于目标值,则目标值只可能在左半部分,因此将搜索范围缩小为左半部分,再次进行二分查找。

5.中间元素小于目标值

如果中间元素小于目标值,则目标值只可能在右半部分,因此将搜索范围缩小为右半部分,再次进行二分查找。

6.重复

重复以上步骤,直到找到目标值或者确定目标值不在数组中。

三、使用条件

数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一。

四、js版本示例

1.左闭右闭

(right - left) >> 1 这个表达式是一个位运算操作。在这里,>> 是右移位运算符,将操作数向右移动指定的位数。

(right - left) 计算了右边界和左边界之间的距离。

>> 1 将这个距离向右移动一位,相当于除以2。这是因为在计算机中,右移一位相当于将数值除以2,并且效率更高。

/*** @param {number[]} nums* @param {number} target* @return {number}*/
var search = function(nums, target) {// right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间let mid, left = 0, right = nums.length - 1;// 当left=right时,由于nums[right]在查找范围内,所以要包括此情况while (left <= right) {// 位运算 + 防止大数溢出mid = left + ((right - left) >> 1);// 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内if (nums[mid] > target) {right = mid - 1;  // 去左面闭区间寻找} else if (nums[mid] < target) {left = mid + 1;   // 去右面闭区间寻找} else {return mid;}}return -1;
};

2.左闭右开

/*** @param {number[]} nums* @param {number} target* @return {number}*/
var search = function(nums, target) {// right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间let mid, left = 0, right = nums.length;    // 当left=right时,由于nums[right]不在查找范围,所以不必包括此情况while (left < right) {// 位运算 + 防止大数溢出mid = left + ((right - left) >> 1);// 如果中间值大于目标值,中间值不应在下次查找的范围内,但中间值的前一个值应在;// 由于right本来就不在查找范围内,所以将右边界更新为中间值,如果更新右边界为mid-1则将中间值的前一个值也踢出了下次寻找范围if (nums[mid] > target) {right = mid;  // 去左区间寻找} else if (nums[mid] < target) {left = mid + 1;   // 去右区间寻找} else {return mid;}}return -1;
};

五、力扣刷题

1.搜索插入位置

在这里插入图片描述

这道题在原有的基础上增添了一个新的条件:就是找不到元素时要返回元素本该插入的位置

为什么返回的值变成了right+1呢?

这是因为在循环过程中,我们通过不断更新 left 和 right 来缩小搜索范围,最终使得 left 大于 right。而 right 的值恰好是目标值在数组中最后一个小于目标值的元素的索引。所以,插入位置应该在 right 的右侧,即 right + 1 处。

例如,考虑一个有序数组 [1, 3, 5, 6],目标值是 4。在二分查找过程中,最终会有 left = 2 和 right = 1,即 right + 1 = 2,这表示目标值 4 应该插入到索引 2 的位置上。

因此,在这段代码中,返回的是 right + 1,表示目标值应该插入的位置。
力扣数组的其他习题将会在后续持续更新打卡……关注收藏不迷路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/525008.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PV与PVC知多少?解锁CKA认证考点攻略!

往期精彩文章 : 提升CKA考试胜算&#xff1a;一文带你全面了解RBAC权限控制&#xff01;揭秘高效运维&#xff1a;如何用kubectl top命令实时监控K8s资源使用情况&#xff1f;CKA认证必备&#xff1a;掌握k8s网络策略的关键要点提高CKA认证成功率&#xff0c;CKA真题中的节点维…

四个领域,企业官网依然无可替代。

2023-10-23 14:17贝格前端工场 企业官网在以下领域无可替代&#xff1a; 专业性强的领域&#xff1a;如金融、法律、医学等&#xff0c;这些领域专业性很强&#xff0c;需要权威、专业的官网来提供详细、准确的信息1。需要展示企业形象、实力的领域&#xff1a;如制造业、房地…

202441读书笔记|《笠翁对韵》—— 金菡萏,玉芙蓉,酒晕微酡琼杏颊,香尘浅印玉莲双

202441读书笔记|《笠翁对韵》——金菡萏&#xff0c;玉芙蓉&#xff0c;酒晕微酡琼杏颊&#xff0c;香尘浅印玉莲双 《作家榜名著&#xff1a;笠翁对韵》作者李渔&#xff0c;霍俊明。是所有词句都有注音的一本书&#xff0c;轻松学不认识的字&#xff0c;非常朗朗上口的对偶词…

深入解读可视化运维的内容、领域、价值和系统搭建

大家好&#xff0c;我是贝格前端工场&#xff0c;接触过很多可视化运维项目&#xff0c;包括IT、电力、物流、生产制造等&#xff0c;本文系统总结一下可视化运维相关知识&#xff0c;老规矩别忘了关注转发&#xff0c;有事请私信。 一、可视化运维定义 可视化运维是指通过可视…

windows更改账户名

win R输入netplwiz 点击用户名进去&#xff0c; 修改用户名之后重启即可。

CAS 登出方案

1.配置 CAS 服务器端 添加配置cas.logout.followServiceRedirects:true&#xff0c;使支持 CAS 退出时支持输入 service 参数为跳转路径 2.配置客户端服务,添加session清除操作 3.前端文件添加跳转重定向 1) 直接在客户端调用http请求/cas/logout去注销不能携带cookie信息, 无…

Unity L屏幕实现方式(已抛弃)

效果 右侧主要的参数&#xff1a;Line参数能够调整中间线的高度&#xff0c;PointXY能够调整整个下方弯曲图像的比例。 使用的是RenderTexture填充RawImage显示的方式&#xff0c;需要将一张RenderTexture设置位摄像机的输出内容。 ShaderGraph 由于这个采用了一定的数学模型…

海翔ERP getylist_login.do接口存在sql注入漏洞

@[toc] 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 海翔ERP 简介 微信公众号搜索:南风漏洞复…

[贰],万能开篇HelloWorld

1&#xff0c;新建项目 File/New/Project Android/Android Application Project 输入程序名字HelloWorld Next Next 选择Blank Activity 修改为HelloWorldActivity 2&#xff0c;异常点 No resource found that matches the given name Theme.AppCompat.Light import andro…

【vue2基础教程】vue指令

文章目录 前言一、内容渲染指令1.1 v-text1.2 v-html1.3 v-show1.4 v-if1.5 v-else 与 v-else-if 二、事件绑定指令三、属性绑定指令总结 前言 Vue.js 是一款流行的 JavaScript 框架&#xff0c;广泛应用于构建交互性强、响应速度快的现代 Web 应用程序。Vue 指令是 Vue.js 中…

AndroidStudio跑马灯实现

在activity_main.xml中编写如下代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_h…

linux安装部署mmdetection,亲测可行

安装了两天&#xff0c;最后终于成功&#xff0c;这里有一些注意事项&#xff0c;版本对应啥的&#xff1a; 这里是mmdetection与MMCV的版本对应关系&#xff1a; mmdet与mmcv的版本对应有一些包因为版本问题直接pip下载不了&#xff0c;这里直接跑到官网去复制下载命令&#…