当前位置: 首页 > news >正文

算法基础学习——二分查找(附带Java模板)

有单调性的数列一定可以使用二分,没有单调性的题目也可能可以使用二分;

(一)整数二分

二分的本质:

        在某个整数区间内,存在某种性质使得区间内左半边的数都不满足该性质;而右半边的数都满足该性质;那么二分的作用就是找到左右这两个分界点;

1.找满足红色性质的边界点(如图上)

如果是让l等于mid(即找左半边的分界点)则要记得mid = (l+r+1)/2

2.找满足绿色性质的边界点(如图上)

如果是让r等于mid(即找右半边的分界点)则mid = (l+r)/2,不用另外加1;

情况1为什么额外加1? 答:因为在程序中,(l+r)/2是向下取整;当遇到遇到r=l+1(l和r只相差1,数组只有两个元素)的情况,(l+r)/2就等于l,这时候mid=(l+r)/2就是mid=l如下图所示:这次循环相当于没有变化,再次循环也不会有变化,进入死循环;

基本思想:不断缩小答案区间,当区间长度为一时,就是答案;

时间复杂度:平均O(logn) 

步骤:
  1. 先写出基本模板:mid = (l+r)/2

  2. 定义判断条件check()函数

  3. 看应该是让l=mid还是r=mid;如果应该l=mid则把前面的mid改为 mid=(l+r+1)/2

模板:
// 检查x是否满足某种性质  
private static boolean check(int x) {  /* ... */  
}  // 区间[left, right]被划分成[left, mid]和[mid + 1, right]时使用: 
// 或者称之为左二分查询,查找左侧第一个满足条件的数
private static int leftBinarySearch(int[] arr, int left, int right) {  while (left < right) {  int mid = arr[left + right >> 1];  if (check(mid)) {  right = mid;    // check()判断mid是否满足性质  } else {  left = mid + 1;  }  }  return left;  
}  // 区间[left, right]被划分成[left, mid - 1]和[mid, right]时使用:  
// 或者称之为右二分查询,查找右侧最后一个满足条件的数
private static int rightBinarySearch(int[] arr, int left, int right) {  while (left < right) {  int mid = arr[left + right + 1 >> 1];  if (check(mid)) {  left = mid;    // check()判断mid是否满足性质  } else {  right = mid - 1;  // 有加必有减}  }  return left;  
}

(二)浮点数二分

典型问题:求一个数的平方根

基本思想:不断缩小答案区间,当区间长度足够小时(即左右边界之差足够小),边界的值就约等于答案;

时间复杂度:平均O(logn) 

步骤:
  • mid就等于(r+l)/2;

  • while循环判定条件为r-l>1e-8(左右边界之差足够小时结束循环)

模板:
// 检查x是否满足某种性质  
private static boolean check(int x) {  /* ... */  
}  // 区间[left, right]被划分成[left, mid]和[mid + 1, right]时使用: 
// 或者称之为左二分查询,查找左侧第一个满足条件的数
private static int leftBinarySearch(int[] arr, int left, int right) {  while (left < right) {  int mid = arr[left + right >> 1];  if (check(mid)) {  right = mid;    // check()判断mid是否满足性质  } else {  left = mid + 1;  }  }  return left;  
}  // 区间[left, right]被划分成[left, mid - 1]和[mid, right]时使用:  
// 或者称之为右二分查询,查找右侧最后一个满足条件的数
private static int rightBinarySearch(int[] arr, int left, int right) {  while (left < right) {  int mid = arr[left + right + 1 >> 1];  if (check(mid)) {  left = mid;    // check()判断mid是否满足性质  } else {  right = mid - 1;  // 有加必有减}  }  return left;  
}

注意点:

  1. 使用二分一定可以找到一个满足条件的边界点(不会出现无解的情况);

  2. 整数二分中,l和r表示的是区间左右边界的数组下标;当遍历结束后l=r,arr[r] 就是所找的边界点;

  3. 浮点数二分中,l和r表示的不是数组下标,而是左右边界本身;

时间复杂度分析

二分查找(Binary Search)的时间复杂度分析如下:

1. 最好情况(Best Case)

如果目标元素正好是数组的中间元素,那么只需一次比较就能找到,时间复杂度为:

O(1)O(1)

2. 最坏情况(Worst Case)

每次查找都会将搜索范围缩小一半,假设数组长度为 nn,那么最多需要查找的次数是:

T(n)=T(n/2)+O(1)T(n) = T(n/2) + O(1)

展开递归:

T(n)=T(n/4)+O(1)+O(1)=T(n/8)+O(1)+O(1)+O(1)=…T(n) = T(n/4) + O(1) + O(1) = T(n/8) + O(1) + O(1) + O(1) = \dots

直到搜索范围缩小到 1,即 n/2k=1n/2^k = 1,解得:

k=log⁡2nk = \log_2 n

因此,最坏情况下的时间复杂度是:

O(log⁡n)O(\log n)

3. 平均情况(Average Case)

在没有额外信息的情况下,平均情况下也需要进行大约 O(log⁡n) 级别的比较,因此平均时间复杂度也是:

O(log⁡n)

总结

情况时间复杂度
最好情况O(1)O(1)
最坏情况O(log⁡n)O(\log n)
平均情况O(log⁡n)O(\log n)

二分查找的时间复杂度远优于线性查找(O(n)),但前提是数据必须是有序的,否则需要先进行排序(如快速排序 O(nlog⁡n)),这会影响整体效率。

相关文章:

算法基础学习——二分查找(附带Java模板)

有单调性的数列一定可以使用二分&#xff0c;没有单调性的题目也可能可以使用二分&#xff1b; &#xff08;一&#xff09;整数二分 二分的本质&#xff1a; 在某个整数区间内&#xff0c;存在某种性质使得区间内左半边的数都不满足该性质&#xff1b;而右半边的数都满足该性…...

【llm对话系统】大模型源码分析之llama模型的long context更长上下文支持

1. 引言 Llama模型的一个重要特性是支持长上下文处理。本文将深入分析Llama源码中实现长上下文的关键技术点&#xff0c;包括位置编码(position embedding)的外推方法、注意力机制的优化等。我们将通过详细的代码解析来理解其实现原理。 2. 位置编码的外推实现 2.1 旋转位置…...

单片机基础模块学习——NE555芯片

一、NE555电路图 NE555也称555定时器,本文主要利用NE555产生方波发生电路。整个电路相当于频率可调的方波发生器。 通过调整电位器的阻值,方波的频率也随之改变。 RB3在开发板的位置如下图 测量方波信号的引脚为SIGHAL,由上面的电路图可知,NE555已经构成完整的方波发生电…...

Hive:struct数据类型,内置函数(日期,字符串,类型转换,数学)

struct STRUCT&#xff08;结构体&#xff09;是一种复合数据类型&#xff0c;它允许你将多个字段组合成一个单一的值, 常用于处理嵌套数据&#xff0c;例如当你需要在一个表中存储有关另一个实体的信息时。你可以使用 STRUCT 函数来创建一个结构体。STRUCT 函数接受多个参数&…...

最优化问题 - 内点法

以下是一种循序推理的方式&#xff0c;来帮助你从基础概念出发&#xff0c;理解 内点法&#xff08;Interior-Point Method, IPM&#xff09; 是什么、为什么要用它&#xff0c;以及它是如何工作的。 1. 问题起点&#xff1a;带不等式约束的优化 假设你有一个带不等式约束的优…...

vim交换文件的工作原理

在vim中&#xff0c;交换文件是一个临时文件&#xff0c;当我们使用vim打开一个文件进行编辑&#xff08;一定得是做出了修改才会产生交换文件&#xff09;时候&#xff0c;vim就会自动创建一个交换文件&#xff0c;而之后我们对于文件的一系列修改都是在交换文件中进行的&…...

CISCO路由基础全集

第一章&#xff1a;交换机的工作原理和基本技能_交换机有操作系统吗-CSDN博客文章浏览阅读1.1k次&#xff0c;点赞24次&#xff0c;收藏24次。交换机可看成是一台特殊的计算机&#xff0c;同样有CPU、存储介质和操作系统&#xff0c;只是与计算机的稍有不同。作为数据交换设备&…...

网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;网络直播作为一种新兴的、极具影响力的媒体形式&#xff0c;正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示&#xff0c;网络直播用户规模已达到3.25亿&#xff0c;占网民总数的45.8…...

2024年终总结——今年是蜕变的一年

2024年终总结 摘要前因转折找工作工作的成长人生的意义 摘要 2024我从国企出来&#xff0c;兜兜转转还是去了北京&#xff0c;一边是工资低、感情受挫&#xff0c;一边是压力大、项目经历少&#xff0c;让我一度找不到自己梦寐以求的工作&#xff0c;我投了一家又一家&#xff…...

AutoDL 云服务器:普通 用户 miniconda 配置

AutoDL 初始状态下只有root用户&#xff0c;miniconda 安装在root用户目录下 /// 增加普通用户 rootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt updaterootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt install sudorootautodl-container-1c0641804d-5…...

渲染流程概述

渲染流程包括 CPU应用程序端渲染逻辑 和 GPU渲染管线 一、CPU应用程序端渲染逻辑 剔除操作对物体进行渲染排序打包数据调用Shader SetPassCall 和 Drawcall 1.剔除操作 视椎体剔除 &#xff08;给物体一个包围盒&#xff0c;利用包围盒和摄像机的视椎体进行碰撞检测&#xf…...

前端力扣刷题 | 4:hot100之 子串

560. 和为K的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 法一&#xff1a;暴力法 var subar…...

Julia 之 @btime 精准测量详解

Julia 语言因其高性能和易用性在科学计算、数据分析等领域获得了广泛关注。在性能优化中&#xff0c;精准测量代码执行时间是至关重要的任务&#xff0c;而 Julia 提供了强大的工具 btime 来辅助这一任务。本文将围绕 Julia 的 btime 来展开&#xff0c;帮助读者深入理解并高效…...

【Django教程】用户管理系统

Get Started With Django User Management 开始使用Django用户管理 By the end of this tutorial, you’ll understand that: 在本教程结束时&#xff0c;您将了解&#xff1a; Django’s user authentication is a built-in authentication system that comes with pre-conf…...

【机器学习】自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测

一、使用pytorch框架实现逻辑回归 1. 数据部分&#xff1a; 首先自定义了一个简单的数据集&#xff0c;特征 X 是 100 个随机样本&#xff0c;每个样本一个特征&#xff0c;目标值 y 基于线性关系并添加了噪声。将 numpy 数组转换为 PyTorch 张量&#xff0c;方便后续在模型中…...

C语言连接Mysql

目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一&#xf…...

Windows上通过Git Bash激活Anaconda

在Windows上配置完Anaconda后&#xff0c;普遍通过Anaconda Prompt激活虚拟环境并执行Python&#xff0c;如下图所示&#xff1a; 有时需要连续执行多个python脚本时&#xff0c;直接在Anaconda Prompt下可以通过在以下方式&#xff0c;即命令间通过&&连接&#xff0c;…...

面试经典150题——图

文章目录 1、岛屿数量1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、被围绕的区域2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、克隆图3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、除法求值4.1 题目链接4.2 题目描述4.3 解题代码4.4 解题思路 5、课…...

学习数据结构(1)时间复杂度

1.数据结构和算法 &#xff08;1&#xff09;数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在⼀种或多种特定关系的数据元素的集合 &#xff08;2&#xff09;算法就是定义良好的计算过程&#xff0c;取一个或一组的值为输入&#xff0c;并产生出一个或一组…...

项目集成GateWay

文章目录 1.环境搭建1.创建sunrays-common-cloud-gateway-starter模块2.目录结构3.自动配置1.GateWayAutoConfiguration.java2.spring.factories 3.pom.xml4.注意&#xff1a;GateWay不能跟Web一起引入&#xff01; 1.环境搭建 1.创建sunrays-common-cloud-gateway-starter模块…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...