二分查找(多版本)

news2025/1/11 7:55:52

1.基础版

public class erfenchazhao {
    public int test(int arr[],int target){
        int i = 0;    //定义左指针
        int j = arr.length-1;//定义右指针
        int m;    //定义中间值
        while(i<=j){    //判断条件
            m = (i+j)>>>1;
            if(target < arr[m]){  //目标值在左边
                j = m - 1;
            }else if ( arr[m] < target ){  //目标值在右边
                i = m + 1;
            }else {     //找到目标值
                return m;
            }
        }
        return -1;
    }
}

注意:

(1)i<=j 最后一次比较当i=j时,它们所指向的元素也会参与比较

(2)m=(i+j)/2有问题,当值达到上界时,m会变为负数, m = (i+j)>>>1避开了该问题,其值为(i+j)/2向下取整

(3)该数组必须是有序的,比较中都使用小于号,方便观察算法

时间复杂度:

最坏情况:O(logn)   

最好情况:如果待查找元素恰好在数组中央,只需要循环一次O(1)

空间复杂度:

需要常数个指针i,j,m,因此额外占用的空间是O(1)

2.改动版

public class erfenchazhao {
    public int test(int arr[],int target){
        int i = 0;   
        int j = arr.length;        //第一处
        int m;   
        while(i < j){              //第二处
            m = (i+j)>>>1;
            if(target < arr[m]){  
                j = m;             //第三处
            }else if ( arr[m] < target ){  
                i = m + 1;
            }else {     
                return m;
            }
        }
        return -1;
    }
}

:改良版的j指向数组外,则j所指位置的值一定不是目标值;

       改良版的i<j,若是<=,则查找不存在的值时,会陷入死循环。

3.平衡版

public class ddd {
    public int search(int a[],int target){
        int i = 0,j = a.length;
        while (1 < j - i){
            int m = (i + j) >>> 1;
            if (target < a[m]){
                j = m;
            } else {
                i = m;
            }
        }
        if (a[i] == target){
            return i;
        }else {
            return -1;
        }
    }
}

优点:循环内的平均比较次数减少了

缺点:必须在循环结束后才能进行 i 指针所指元素与目标元素的比较,时间复杂度都是O(logn)

4.java版

在java可以直接调用该方法,查找数组中某个值的位置(仅适用于有序数组

若是没有找到,返回 -(low+1) (即负数表示没找到),则low代表该值 若是插入数组 应插入的位置,+1是排除该值插入0号位置的情况

扩展:将目标值插入数组

5.LeftRightmost(有重复元素的数组)

适用于有序数组

(1)寻找目标值最左边的位置
public class erfenchazhao {
    public int test1(int arr[],int target){
        int i = 0, j = arr.length-1;
        int candidate = -1;
        while(i<=j){    
            int m = (i+j)>>>1;
            if(target < arr[m]){  
                j = m - 1;
            }else if (arr[m] < target){  
                i = m + 1;
            }else { 
                //记录候选位置
                candidate = m;
                j = m - 1;
            }
        }
        return candidate;
    }
}
(2)寻找目标值最右边的位置
public class erfenchazhao {
    public int test1(int arr[],int target){
        int i = 0, j = arr.length-1;
        int candidate = -1;
        while(i<=j){
            int m = (i+j)>>>1;
            if(target < arr[m]){
                j = m - 1;
            }else if (arr[m] < target){
                i = m + 1;
            }else {
                //记录候选位置
                candidate = m;
                i = m + 1;
            }
        }
        return candidate;
    }
}

6.LeftRightmost优化

(1)靠左
public class erfenchazhao {
    public int test1(int arr[],int target){
        int i = 0, j = arr.length-1;
        while(i<=j){    
            int m = (i+j)>>>1;
            if(target <= arr[m]){  
                j = m - 1;
            }else {  
                i = m + 1;
            }
        }
        return i;
    }
}

返回值含义:返回 >= target 的最靠左索引

(2)靠右
public class erfenchazhao {
    public int test1(int arr[],int target){
        int i = 0, j = arr.length-1;
        while(i<=j){
            int m = (i+j)>>>1;
            if(target < arr[m]){
                j = m - 1;
            }else{
                i = m + 1;
            }
        }
        return i - 1;
    }
}

返回值含义:返回 <= target 的最靠右索引

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】在Python代码中执行Linux命令的详细用法教程

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

昇思25天学习打卡营第01天|昇思MindSpore大模型基础介绍

昇思MindSpore和华为昇思MindSpore大模型学习打卡系列文章&#xff0c;本文仅供参考~ 文章目录 前言一、昇思MindSpore是什么&#xff1f;二、执行流程三、设计理念四、层次结构五、Huawei昇腾AI全栈 前言 随着计算机大模型的不断发展&#xff0c;Ai这门技术也越来越重要&#…

免费【2024】springboot 宠物领养救助平台的开发与设计

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Prozyme糖样本检测平台--GlykoPrep® Rapid N-Glycan Preparation with APTS

单克隆抗体已成为生物制药行业具有潜力的新兴蛋白候选药物。其药物研发流程包括一系列精细的控制和评估步骤&#xff0c;需要仔细、严格地监测目标化合物的治疗稳定性及有效性。因此&#xff0c;在商业化前的每个阶段对单克隆抗体进行全面表征是极其有益的。在大量研究成熟的蛋…

用Python打造精彩动画与视频,3.1 安装和设置 MoviePy

第3章 开始你的第一个视频项目 MoviePy 3.1 安装和设置 MoviePy 视频处理在多媒体内容创作中起着至关重要的作用。MoviePy 是一个用于视频编辑的 Python 库&#xff0c;它可以让你轻松地进行视频剪辑、合并、特效添加等操作。通过 MoviePy&#xff0c;你可以用简单的 Python…

基于Java+SpringBoot+Vue的的课程作业管理系统

前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 哈喽兄弟们&#xff0c;好久不见哦&#xff5…

IEEE 快刊合集!期刊选的好,JCR1区照样轻松拿下~

【SciencePub学术】今天小编给大家推荐2本计算机领域的SCI&#xff0c;均隶属于IEEE出版社&#xff0c;虽比不上前几日给大家介绍的IEEE-Trans系列的那本期刊优秀&#xff0c;但是放在行业内还是很拿得出手的。 现在提交&#xff0c;可免费预审&#xff0c;预审通过后录用率100…

失业负债女孩,下班后用AI做副业,快速翻身上岸

** - 我们应该把负债看成是成长的助力&#xff0c;而不是搞垮骆驼的稻草。 负债上岸&#xff0c;没有更多的捷径&#xff0c;唯有“开源节流”&#xff0c;节流就是尽可能节约花费&#xff0c;把生活支出减少&#xff0c;开源就是尽可能多的增加自己的副业收入。 负债后的至…

【通俗理解】“多即不同”观念的科学内涵——从对称破缺到科学层次结构的探索

【通俗理解】“多即不同”观念的科学内涵——从对称破缺到科学层次结构的探索 对称破缺与科学层次结构的类比 你可以把对称破缺比作一个“建筑师”&#xff0c;它构建了科学大厦的基础框架。而科学层次结构则是一个“城市规划师”&#xff0c;它规划了这些基础框架如何组合成一…

【附精彩文章合辑】跨界对话:黄仁勋与扎克伯格的“外套交换”与未来展望

跨界对话&#xff1a;黄仁勋与扎克伯格的“外套交换”与未来展望 在科技界的浩瀚星空中&#xff0c;两位璀璨的名字如同双子星般交相辉映——NVIDIA的创始人兼CEO黄仁勋&#xff08;Jensen Huang&#xff09;与Facebook&#xff08;现更名为Meta&#xff09;的掌舵人马克扎克伯…

快速开启react+electron应用,搭建启动问题

注意&#xff1a; React 本地启动在 3000端口Electron 在创建 BrowserWindow 的时候&#xff0c;可以读取本地的文件或者是 url开发环境 读取localhost: 3000生产环境 需要加载本地成型以后的本地文件&#xff0c;打包的时候再考虑 一 react 脚手架 create-react-app 快速搭建…

iTerm2使用手册

iTerm2字体 参考文章&#xff1a;iTerm2 安装 SF Mono 字体 iTerm2默认的字体不太好看&#xff0c;感觉Mac自带的终端的字体看起来很舒服&#xff0c;于是让iTerm2和Mac自带终端保持一致 找到Terminal.app下面的字体 执行 cp *.otf ~/Library/Fonts/ 然后在iTerm2中设置字…

ElementUI,el-input输入框max、min限制最大最小值失效

<el-input type"number" v-model"loadNodesNum" :min"1" :max"5" style"width: 240px;overflow: hidden;"><el-button slot"append" click"handleMaxLoadNum(1)">负载最多的节点TOP</el…

记一次JS到WAF绕过上传

一、前言 某渗透项目中和队友配合挖到一个通用系统漏洞&#xff0c;主要对JS接口进行分析&#xff0c;经历一波绕waf的曲折最终getshell&#xff0c;文笔粗劣&#xff0c;大佬勿喷。 二、JS分析 在看到某系统仅仅一个登陆框&#xff0c;一波弱口令尝试和目录扫描&#xff0c…

PHP教务排课系统小程序源码

教务排课系统&#xff1a;智慧教育的新篇章 &#x1f4da; 开篇&#xff1a;告别手动排课的繁琐时代 在这个信息爆炸的时代&#xff0c;教育领域的每一个细节都在向智能化迈进。你是否还记得&#xff0c;曾经老师们为了编排一张完美的课程表&#xff0c;需要花费多少时间和精…

JMeter接口测试-5.JMeter高级使用

JMeter高级使用 案例&#xff1a; 用户登录后-选择商品-添加购物车-创建订单-验证结果 问题&#xff1a; JMeter测试中&#xff0c;验证结果使用断言&#xff0c;但断言都是固定的内容假如要判断的内容(预期内容)是在变化的, 有时候还是不确定的, 那该怎么办呢? 解决&…

【MySQL】访问mysqld的方式{命令行客户端/vscode-c-api客户端/图形化界面:mysql/navicat}

文章目录 1.访问数据库2.vscode-c-api客户端方法一&#xff1a;重新安装相关数据方法二&#xff1a;直接使用之间安装mysql的附加数据查看mysql文档方式使用c-mysql-api库访问mysqld代码理解mysql_res 3.图形化界面 1.访问数据库 命令行式客户端向mysqld下达指令 网页版 图形化…

ViVim编辑器

文章目录 基本介绍常用的三种模式1. 正常模式2. 插入模式3. 命令行模式 常用快捷键环境参数配置光标移动查找与替换删除复制粘贴模式切换 基本介绍 Linux 系统会内置 vi 文本编辑器 Vi是最早的文本编辑器之一&#xff0c;主要用于Linux和Unix操作系统中的文本编辑。它是一个纯…

Kafka动态授权认证:利用SASL/SCRAM机制提升安全性

摘要 Apache Kafka是一个流行的分布式流处理平台&#xff0c;其安全性对于保护数据传输至关重要。SASL/SCRAM&#xff08;Simple Authentication and Security Layer/Salted Challenge Response Authentication Mechanism&#xff09;是一种认证机制&#xff0c;可以为Kafka集…

Spring-原理篇-DispatcherServlet 初始化 怎么和IOC进行了打通?

委托模式的体现&#xff0c;在初始化醒目的时候Spring MVC为我们提供了一个DispatcherServlet&#xff0c;映射了所有的路径&#xff0c;所有的请求都会先到达这里然后被转发到具体的Controller 进行处理&#xff0c;此文来探索一下&#xff0c;DispatcherServlet 初始化的时候…