算法基础学习——二分查找(附带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)
步骤:
-
先写出基本模板:mid = (l+r)/2
-
定义判断条件check()函数
-
看应该是让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;
}
注意点:
-
使用二分一定可以找到一个满足条件的边界点(不会出现无解的情况);
-
整数二分中,l和r表示的是区间左右边界的数组下标;当遍历结束后l=r,arr[r] 就是所找的边界点;
-
浮点数二分中,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=log2nk = \log_2 n
因此,最坏情况下的时间复杂度是:
O(logn)O(\log n)
3. 平均情况(Average Case)
在没有额外信息的情况下,平均情况下也需要进行大约 O(logn) 级别的比较,因此平均时间复杂度也是:
O(logn)
总结
| 情况 | 时间复杂度 |
|---|---|
| 最好情况 | O(1)O(1) |
| 最坏情况 | O(logn)O(\log n) |
| 平均情况 | O(logn)O(\log n) |
二分查找的时间复杂度远优于线性查找(O(n)),但前提是数据必须是有序的,否则需要先进行排序(如快速排序 O(nlogn)),这会影响整体效率。
相关文章:
算法基础学习——二分查找(附带Java模板)
有单调性的数列一定可以使用二分,没有单调性的题目也可能可以使用二分; (一)整数二分 二分的本质: 在某个整数区间内,存在某种性质使得区间内左半边的数都不满足该性质;而右半边的数都满足该性…...
如何使用formlinker,重构微软表单创建的数字生产力法则?
仅需三步:上传文件-下载文件-导入文件到微软表单 凌晨两点的格式炼狱:被浪费的300万小时人类创造力 剑桥大学的实验室曾捕捉到一组震撼数据:全球教育工作者每年花在调整试题格式上的时间,足够建造3座迪拜哈利法塔。当北京某高校的…...
python-leetcode-路径总和
112. 路径总和 - 力扣(LeetCode) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:de…...
乐理笔记——DAY01
三分钟音乐社视频地址: 【四川音乐学院作曲硕士】零基础自学音乐学乐理合集-第二季(最终版)/已完结https://www.bilibili.com/video/BV14p4y1e7TV?spm_id_from333.788.videopod.episodes&vd_source0a2d366696f87e241adc64419bf12cab&am…...
使用DeepSeek技巧:提升内容创作效率与质量
一、引言 在当今快节奏的数字时代,内容创作的需求不断增加,无论是企业营销、个人博客还是学术研究,高效且高质量的内容生成变得至关重要。DeepSeek作为一款先进的人工智能写作助手,凭借其强大的语言生成能力,为创作者…...
视频编辑系列——Shotcut如何裁切视频黑边并放大画面导出
会议录屏经常出现不满屏的现象(图1),通过本方法可以调整为图2。 图1 图2 打开shotcut,将待裁剪视频导入,将视频拖到时间线。顶部菜单栏点击“滤镜”,新建一个“尺寸、位置与旋转”的滤镜,然后…...
vim操作简要记录
操作容易忘记,记录一下基本使用的 :wq保存退出 :w :q :q! :wq! i I a A 方向键 h左 j下 k上 l右 dd删除方行(这其实是剪切行操作,不过一般用作删除,长按可删除,不过按.执行上一次操作删除更快) .执行上…...
小南每日 AI 资讯 | AI模型扩展的快速增长时代正在放缓 | 25/01/30
AI模型扩展的挑战:随着研究人员发现单纯通过增加规模和计算能力难以获得更大回报,AI模型扩展的快速增长时代正在放缓。 GPT-5开发延迟:OpenAI雄心勃勃的GPT-5项目(代号:Orion)面临着显著的障碍,…...
《DeepSeek 对话实录》
《DeepSeek 对话实录》 你是DeepSeek哪个版本?一、DeepSeek key如何申请1. 访问DeepSeek官网:2. 注册或登录:3. **进入API管理页面**:4. 申请API密钥:5. 提交申请:6. 等待审核:7. 使用API密钥&a…...
FastAPI + GraphQL + SQLAlchemy 实现博客系统
本文将详细介绍如何使用 FastAPI、GraphQL(Strawberry)和 SQLAlchemy 实现一个带有认证功能的博客系统。 技术栈 FastAPI:高性能的 Python Web 框架Strawberry:Python GraphQL 库SQLAlchemy:Python ORM 框架JWT&…...
React第二十八章(css modules)
css modules 什么是 css modules 因为 React 没有Vue的Scoped,但是React又是SPA(单页面应用),所以需要一种方式来解决css的样式冲突问题,也就是把每个组件的样式做成单独的作用域,实现样式隔离,而css modules就是一种…...
昆仑万维Java开发面试题及参考答案
进程和线程的区别是什么? 进程和线程都是操作系统中非常重要的概念,它们在多个方面存在显著的区别。 从定义上看,进程是操作系统进行资源分配和调度的基本单位。每个进程都有自己独立的内存空间,包括代码段、数据段、堆栈段等。例如,当你在电脑上同时打开浏览器和音乐播放…...
DeepSeek R1-Zero vs. R1:强化学习推理的技术突破与应用前景
📌 引言:AI 推理的新时代 近年来,大语言模型(LLM) 的规模化扩展成为 AI 研究的主流方向。然而,LLM 的扩展是否真的能推动 通用人工智能(AGI) 的实现?DeepSeek 推出的 R1…...
Linux《基础指令》
在之前的Linux《Linux简介与环境的搭建》当中我们已经初步了解了Linux的由来和如何搭建Linux环境,那么接下来在本篇当中我们就要来学习Linux的基础指令。在此我们的学习是包括两个部分,即指令和关于Linux的基础知识;因此本篇指令和基础知识的…...
2024.12.28测试 总结
还是超级无敌寀啊~ 目录 T1 赠送笔记本T2 中位数T3 好子集T4 异或总结 T1 赠送笔记本 link 题意 有 n n n 个宿舍,每个宿舍 4 4 4 头奶牛,第 i i i 个宿舍有 a i a_i ai 头牛有笔记本(每头牛的笔记本都不同)。现在所有奶…...
工业相机开发操作流程
建议按照如下的流程操作相机(其中有一些步骤是可选的,已经标明): 一、载入SDK的动态链接库档MVCAMSDK.DLL。可以使用动态或者静 态加载两种方式。 如果使用C/C进行开发,在工程引用 CameraApi.h头文件(位于安装目录的SDK/DEMO/VC/include中)和…...
DeepSeek-R1 模型及GRPO算法学习
总结DeepSeek-R1 模型算法,并对其中的GRPO算法做一些学习补充。 DeepSeek-R1 论文总结 提出了通过强化学习提升大语言模型推理能力的方法,开发出 DeepSeek-R1-Zero 和 DeepSeek-R1 模型,在多个推理任务上表现出色,并开源模型推动…...
Vue 3.0打造响应式用户界面的新方式
1 简介 Vue.js 是一个用于构建用户界面的渐进式框架。Vue 3.0 是其最新版本,引入了许多新特性和改进,使得开发者能够更高效地构建响应式的Web应用程序。本文将带你深入了解如何使用Vue 3.0来打造响应式用户界面,并通过实际案例和代码示例帮助你快速上手。 2 环境搭建 要开…...
爬虫基础(二)Web网页的基本原理
一、网页的组成 网页由三部分构成:HTML、JavaScript、CSS。 (1)HTML HTML 相当于网页的骨架,它通过使用标签来定义网页内容的结构。 举个例子: 它把图片标签为img、把视频标签为video,然后组合到一个界面…...
Kotlin开发(六):Kotlin 数据类,密封类与枚举类
引言 想象一下,你是个 Kotlin 开发者,敲着代码忽然发现业务代码中需要一堆冗长的 POJO 类来传递数据。烦得很?别急,Kotlin 贴心的 数据类 能帮你自动生成 equals、hashCode,直接省时省力!再想想需要多种状…...
我的AI工具箱Tauri+Django内容生产介绍和使用
在现代内容生产环境中,高效、自动化的工具能够显著提升生产力,降低人工成本。Tauri 与 Django 结合打造的工作箱,集成了强大的 音频处理、视频剪辑、内容下载 以及 AI 文章撰写 等模块,帮助用户在多媒体内容生产的各个环节实现高效…...
openssl 生成证书 windows导入证书
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
AJAX笔记入门篇
黑马程序员视频地址: 黑马程序员前端AJAX入门到实战全套教程https://www.bilibili.com/video/BV1MN411y7pw?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p2https://www.bilibili.com/video/BV1MN411y7pw?vd_source…...
DOM操作中childNodes与children的差异及封装方案
引言 在JavaScript的DOM操作中,childNodes和children是开发者常用的属性,但它们在浏览器中的行为差异可能导致兼容性问题。尤其是在处理空白符(如换行符\n)时,某些浏览器(如Chrome和Edge)会将空…...
数据分析系列--④RapidMiner进行关联分析(案例)
一、核心概念 1.1项集(Itemset) 1.2规则(Rule) 1.3支持度(Support) 1.3.1 支持度的定义 1.3.2 支持度的意义 1.3.3 支持度的应用 1.3.4 支持度的示例 1.3.5 支持度的调整 1.3.6 支持度与其他指标的…...
危机13小时:追踪一场GitHub投毒事件
事件概要 自北京时间 2024.12.4 晚间6点起, GitHub 上不断出现“幽灵仓库”,仓库中没有任何代码,只有诱导性的病毒文件。当天,他们成为了 GitHub 上 star 增速最快的仓库。超过 180 个虚假僵尸账户正在传播病毒,等待不…...
LLMs之WebRAG:STORM/Co-STORM的简介、安装和使用方法、案例应用之详细攻略
LLMs之WebRAG:STORM/Co-STORM的简介、安装和使用方法、案例应用之详细攻略 目录 STORM系统简介 1、Co-STORM 2、更新新闻 STORM系统安装和使用方法 1、安装 pip安装 直接克隆GitHub仓库 2、模型和数据集 两个数据集 FreshWiki数据集 WildSeek数据集 支持…...
使用QSqlQueryModel创建交替背景色的表格模型
class UserModel(QSqlQueryModel):def __init__(self):super().__init__()self._query "SELECT name, age FROM users"self.refresh()def refresh(self):self.setQuery(self._query)# 重新定义data()方法def data(self, index, role): if role Qt.BackgroundRole…...
低代码产品插件功能一览
下图是统计的目前市面上流行的低代码、零代码产品的插件功能。 产品名称 产品类型 官方插件数量 支持拓展 官方插件功能 宜搭 零代码 3 暂不支持 云打印、CAD看图、打印表单详情 微搭 低代码 1 暂不支持 小程序 明道云 低代码 2 支持 视图、工作流节点 简道…...
buu-rip-好久不见26
简单的栈溢出,找到后面函数和输入的个数即可...
