国家住房和城乡建设部中国建造师网站官网/外贸网
1.概念
二分查找算法也称折半查找,是一种非常高效的工作于有序数组的查找算法。
需求:在有序数组 A A A 内,查找值 t a r g e t target target
- 如果找到返回索引
- 如果找不到返回 − 1 -1 −1
前提 | 给定一个内含 n n n 个元素的有序数组 A A A,满足 A 0 ≤ A 1 ≤ A 2 ≤ ⋯ ≤ A n − 1 A_{0}\leq A_{1}\leq A_{2}\leq \cdots \leq A_{n-1} A0≤A1≤A2≤⋯≤An−1,一个待查值 t a r g e t target target |
---|---|
1 | 设置 i = 0 i=0 i=0, j = n − 1 j=n-1 j=n−1 |
2 | 如果 i > j i \gt j i>j,结束查找,没找到 |
3 | 设置 m = f l o o r ( i + j 2 ) m = floor(\frac {i+j}{2}) m=floor(2i+j) , m m m 为中间索引, f l o o r floor floor 是向下取整( ≤ i + j 2 \leq \frac {i+j}{2} ≤2i+j 的最小整数) |
4 | 如果 t a r g e t < A m target < A_{m} target<Am 设置 j = m − 1 j = m - 1 j=m−1,跳到第2步 |
5 | 如果 A m < t a r g e t A_{m} < target Am<target 设置 i = m + 1 i = m + 1 i=m+1,跳到第2步 |
6 | 如果 A m = t a r g e t A_{m} = target Am=target,结束查找,找到了 |
2.基础版
public static int binarySearch(int[] arr, int target) {int min = 0, max = arr.length - 1;while (min <= max) {int mid = (max + min) >>> 1;//无符号右移int midVal = arr[mid];if (target < midVal) {max = mid - 1;} else if (midVal < target) {min = mid + 1;} else {return mid;}}return -1;
}
3.改动版
public static int binarySearch(int[] arr, int target) {int min = 0, max = arr.length;while (min < max) {int mid = (max + min) >>> 1;//无符号右移int midVal = arr[mid];if (target < midVal) {max = mid;} else if (midVal < target) {min = mid + 1;} else {return mid;}}return -1;
}
4.衡量算法的好坏
对比线性查找
for (int i = 0; i < arr.length; i++) {if(arr[i] == target){return i;}
}
return -1;
事前分析法
图形计算器
计算机科学中,时间复杂度是用来衡量:一个算法的执行,随数据规模增大,而增长的时间成本
- 不依赖于环境因素
如何表示时间复杂度呢?
-
假设算法要处理的数据规模是 n n n,代码总的执行行数用函数 f ( n ) f(n) f(n) 来表示,例如:
- 线性查找算法的函数 f ( n ) = 3 ∗ n + 3 f(n) = 3*n + 3 f(n)=3∗n+3
- 二分查找算法的函数 f ( n ) = ( f l o o r ( l o g 2 ( n ) ) + 1 ) ∗ 5 + 4 f(n) = (floor(log_2(n)) + 1) * 5 + 4 f(n)=(floor(log2(n))+1)∗5+4
-
为了对 f ( n ) f(n) f(n) 进行化简,应当抓住主要矛盾,找到一个变化趋势与之相近的表示法
大 O O O 表示法
其中
- c , c 1 , c 2 c, c_1, c_2 c,c1,c2 都为一个常数
- f ( n ) f(n) f(n) 是实际执行代码行数与 n 的函数
- g ( n ) g(n) g(n) 是经过化简,变化趋势与 f ( n ) f(n) f(n) 一致的 n 的函数
渐进上界
渐进上界(asymptotic upper bound):从某个常数 n 0 n_0 n0开始, c ∗ g ( n ) c*g(n) c∗g(n) 总是位于 f ( n ) f(n) f(n) 上方,那么记作 O ( g ( n ) ) O(g(n)) O(g(n))
- 代表算法执行的最差情况
例1
- f ( n ) = 3 ∗ n + 3 f(n) = 3*n+3 f(n)=3∗n+3
- g ( n ) = n g(n) = n g(n)=n
- 取 c = 4 c=4 c=4,在 n 0 = 3 n_0=3 n0=3 之后, g ( n ) g(n) g(n) 可以作为 f ( n ) f(n) f(n) 的渐进上界,因此表示法写作 O ( n ) O(n) O(n)
例2
- f ( n ) = 5 ∗ f l o o r ( l o g 2 ( n ) ) + 9 f(n) = 5*floor(log_2(n)) + 9 f(n)=5∗floor(log2(n))+9
- g ( n ) = l o g 2 ( n ) g(n) = log_2(n) g(n)=log2(n)
- O ( l o g 2 ( n ) ) O(log_2(n)) O(log2(n))
已知 f ( n ) f(n) f(n) 来说,求 g ( n ) g(n) g(n)
- 表达式中相乘的常量,可以省略,如
- f ( n ) = 100 ∗ n 2 f(n) = 100*n^2 f(n)=100∗n2 中的 100 100 100
- 多项式中数量规模更小(低次项)的表达式,如
- f ( n ) = n 2 + n f(n)=n^2+n f(n)=n2+n 中的 n n n
- f ( n ) = n 3 + n 2 f(n) = n^3 + n^2 f(n)=n3+n2 中的 n 2 n^2 n2
- 不同底数的对数,渐进上界可以用一个对数函数 log n \log n logn 表示
- 例如: l o g 2 ( n ) log_2(n) log2(n) 可以替换为 l o g 10 ( n ) log_{10}(n) log10(n),因为 l o g 2 ( n ) = l o g 10 ( n ) l o g 10 ( 2 ) log_2(n) = \frac{log_{10}(n)}{log_{10}(2)} log2(n)=log10(2)log10(n),相乘的常量 1 l o g 10 ( 2 ) \frac{1}{log_{10}(2)} log10(2)1 可以省略
- 类似的,对数的常数次幂可省略
- 如: l o g ( n c ) = c ∗ l o g ( n ) log(n^c) = c * log(n) log(nc)=c∗log(n)
常见大 O O O 表示法
按时间复杂度从低到高
- 黑色横线 O ( 1 ) O(1) O(1),常量时间,意味着算法时间并不随数据规模而变化
- 绿色 O ( l o g ( n ) ) O(log(n)) O(log(n)),对数时间
- 蓝色 O ( n ) O(n) O(n),线性时间,算法时间与数据规模成正比
- 橙色 O ( n ∗ l o g ( n ) ) O(n*log(n)) O(n∗log(n)),拟线性时间
- 红色 O ( n 2 ) O(n^2) O(n2) 平方时间
- 黑色朝上 O ( 2 n ) O(2^n) O(2n) 指数时间
- 没画出来的 O ( n ! ) O(n!) O(n!)
空间复杂度
与时间复杂度类似,一般也使用大 O O O 表示法来衡量:一个算法执行随数据规模增大,而增长的额外空间成本
二分查找性能
下面分析二分查找算法的性能
时间复杂度
- 最坏情况: O ( log n ) O(\log n) O(logn)
- 最好情况:如果待查找元素恰好在数组中央,只需要循环一次 O ( 1 ) O(1) O(1)
空间复杂度
- 需要常数个指针 i , j , m i,j,m i,j,m,因此额外占用的空间是 O ( 1 ) O(1) O(1)
5.平衡版
思想:
- 左闭右开的区间, i i i 指向的可能是目标,而 j j j 指向的不是目标
- 不奢望循环内通过 m m m 找出目标, 缩小区间直至剩 1 个, 剩下的这个可能就是要找的(通过 i i i)
- j − i > 1 j - i > 1 j−i>1 的含义是,在范围内待比较的元素个数 > 1
- 改变 i i i 边界时,它指向的可能是目标,因此不能 m + 1 m+1 m+1
- 循环内的平均比较次数减少了
- 时间复杂度 Θ ( l o g ( n ) ) \Theta(log(n)) Θ(log(n))
public static int binarySearch(int[] arr, int target) {int min = 0, max = arr.length;while (1 < max - min) {int mid = (min + max) >>> 1;if (target < arr[mid]) {max = mid;} else {min = mid;}}return (arr[min] == target) ? min : -1;
}
6.Leftmost 查询最左侧重复元素
public static int leftMost(int[] arr, int target) {int min = 0, max = arr.length - 1;int result = -1;//记录候选位置while (min <= max) {int mid = (min + max) >>> 1;int midVal = arr[mid];if (target < midVal) {max = mid - 1;} else if (midVal < target) {min = mid + 1;} else {result = mid;max = mid - 1;}}return result;
}
返回 >=target 的最靠左索引
- leftmost 返回值的另一层含义: < t a r g e t \lt target <target 的元素个数
- 小于等于中间值,都要向左找
public static int leftMost(int[] arr, int target) {int min = 0, max = arr.length - 1;while (min <= max) {int mid = (min + max) >>> 1;if (target <= arr[mid]) {max = mid - 1;} else {min = mid + 1;}}//返回 >=target 的最靠左索引return min;
}
7.Rightmost 查询最右侧重复元素
public static int rightMost(int[] arr, int target) {int min = 0, max = arr.length - 1;int result = -1;while (min <= max) {int mid = (min + max) >>> 1;int midVal = arr[mid];if (target < midVal) {max = mid - 1;} else if (midVal < target) {min = mid + 1;} else {result = mid;min = mid + 1;}}return result;
}
返回<=target 的最靠右索引
大于等于中间值,都要向右找
public static int rightMost(int[] arr, int target) {int min = 0, max = arr.length - 1;while (min <= max) {int mid = (min + max) >>> 1;if(target < arr[mid]){max = mid - 1;}else{min = mid + 1;}}//返回<=target 的最靠右索引return min - 1;
}
8.Leetcode 练习
- 704题
- 35题
- 34题
相关文章:

初识算法——二分查找
1.概念 二分查找算法也称折半查找,是一种非常高效的工作于有序数组的查找算法。 需求:在有序数组 A A A 内,查找值 t a r g e t target target 如果找到返回索引如果找不到返回 − 1 -1 −1 前提给定一个内含 n n n 个元素的有序数组…...

深入剖析 Java Spring 中的 @Autowired、@Resource、@Qualifier、@Inject 注解:使用详解与注意事项
文章目录 Autowired:Spring 最常用的注解1. 作用与简介2. 使用示例3. 注意事项 Resource:按名称注入的利器1. 作用与简介2. 使用示例3. 注意事项 Qualifier:解决多 bean 注入问题1. 作用与简介2. 使用示例3. 注意事项 Inject:标准…...

ThingsBoard规则链节点:Delete Attributes节点详解
引言 删除属性节点简介 用法 含义 应用场景 实际项目运用示例 智能家居安全系统 物流跟踪解决方案 工业自动化生产线 结论 引言 ThingsBoard是一个开源的物联网平台,它提供了设备管理、数据收集与处理以及实时监控等功能。其中,规则引擎是其核心…...

关于作为面试官以及如何准备面试的一些心得
关于作为面试官以及如何准备面试的一些心得 一、面试官(我站在前端角度来说) 当作为这样身份的时候,我想第一步应该是自己梳理一些从简到难、从点到面的问题 CSS - JS - 框架 - 项目 从这四个角度出发,一步一步的引导面试者的思…...

Bean对象 和 普通对象 的区别
Bean对象 和 普通对象 的区别 前言Bean的概念与new创建的对象的区别Spring Bean的优势两者使用的关键点总结 前言 在Spring框架中,我们通常将Spring容器管理的对象称为“Bean”或“Bean对象”。而通过new关键字创建的对象则被称为“对象”或“普通对象”。 Bean的…...

lego-loam featureAssociation 源码注释(二)
咱们接着往下看initializationValue();!!! FeatureAssociation():nh("~"){subLaserCloud nh.subscribe<sensor_msgs::PointCloud2>("/segmented_cloud", 1, &FeatureAssociation::laserCloudHandler, this);s…...

Claude 3.5 的六大应用场景
Claude 3.5 的六大应用场景 随着人工智能技术的飞速发展,Claude 3.5 已经成为一款强大的语言模型工具,在多个领域展现了其卓越的应用潜力。本文将通过CSDN格式,介绍Claude 3.5在六大主要领域的实际应用场景,帮助开发者和企业更好…...

进程线程知识总结
1. 程序什么时候应该使用线程,什么时候单线程效率高 使用线程:在I/O密集型或高并发的场景,例如网络服务、文件读写等。通过多线程可以同时处理多个任务,提高利用率。单线程效率高:在CPU密集型任务中,当任务…...

Rsync数据复制/备份服务应用
文章目录 1. rsync概述1.1 什么是Rsync1.2 rsync的功能1.3 rsync 的功能特性1.4 Rsync 增量复制原理1.5 生产场景架构集群备份方案 2. Rsync工作方式介绍与实践2.1 本地数据传输模式2.1.1 本地数据传输模式语法2.1.2 本地数据传输模式实践 2.2 远程Shell 数据传输模式2.2.1 远程…...

如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发
如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发 在全球化的浪潮下,跨境电商成为越来越多企业拓展国际市场的重要途径。然而,语言障碍成为了一个不可忽视的问题。为了更好地服务全球用户,为自己的跨境网站添加多国语言…...

安全见闻(3)——开阔眼界,不做井底之蛙
内容预览 ≧∀≦ゞ 安全见闻三:脚本程序与病毒声明导语脚本语言BAT/PowerShell脚本木马与宏病毒脚本病毒BIOS病毒 结语 安全见闻三:脚本程序与病毒 声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只…...

MySQL 的意向锁(Intention Locks)原理详解
1. 背景:为什么需要意向锁? MySQL 中意向锁的主要作用是用于支持行级锁与表级锁的并存,特别是在 InnoDB 存储引擎中。InnoDB 提供了行级锁,而在某些场景下,数据库系统仍需要对整张表加锁,例如 LOCK TABLES …...

31个省份农业科技水平(农业技术创新或农业科技专利数据)2010-2022年
一、测算方式:参考C刊《湖北大学学报(哲学社会科学版)》张金鑫(2020)老师的做法,采用农业( 农林牧渔业) 三类专利总和来衡量农业技术创新 二、资料范围:31个省份,403个观测值,已经整理成面板数…...

Python代码执行失败问题及解决方案
目录 一、Python代码执行失败的原因 二、常见的Python错误类型 1. 语法错误(SyntaxError) 2. 运行时错误(RuntimeError) 3. 类型错误(TypeError) 4. 导入错误(ImportError) 5…...

Java 遗传算法
遗传算法(Genetic Algorithm, GA)是一种基于自然选择和遗传学原理的优化算法,用于求解复杂的搜索和优化问题。在Java中实现遗传算法通常包括以下几个步骤: 初始化种群:生成一组随机解作为初始种群。适应度评估&#x…...

C++ (一) 基础语法
基础语法:C的开胃小菜 欢迎来到C的世界,这里是编程的盛宴,也是逻辑的迷宫。别担心,我们不会一开始就让你啃硬骨头,而是从基础语法开始,让你慢慢品尝编程的美味。准备好了吗?让我们开始这场编程…...

Qt/C++路径轨迹回放/回放每个点信号/回放结束信号/拿到移动的坐标点经纬度
一、前言说明 在使用百度地图的路书功能中,并没有提供移动的信号以及移动结束的信号,但是很多时候都期望拿到移动的哪里了以及移动结束的信号,以便做出对应的处理,比如结束后需要触发一些对应的操作。经过搜索发现很多人都有这个…...

C 语言介绍及操作案例
C 语言是一种广泛使用的通用编程语言,具有高效、灵活和可移植性强等特点。 一、C 语言的基本特点 简洁高效 C 语言语法简洁,表达能力强。它提供了丰富的数据类型和运算符,可以方便地进行各种计算和操作。C 语言的代码执行效率高,能够直接访问硬件资源,适用于对性能要求较…...

Ivanti云服务被攻击事件深度解析:安全策略构建与未来反思
攻击事件背景 近期,威胁情报和研究机构Fortinet FortiGuard Labs发布了一份关于针对IT解决方案提供商Ivanti云服务设备(Ivanti Cloud Services Appliance,CSA)的复杂网络攻击的详细分析。 该攻击被怀疑是由国家级对手发起…...

如何做出正确选择编程语言:关于Delphi 与 C# 编程语言的优缺点对比
概述 为您的项目选择正确的技术可能是一项相当棘手的任务,尤其是当您以前从未需要做出这样的选择时。如今可用的选项范围非常广泛。虽然一些编程语言和工具有着相当悠久的历史,但其他一些则是刚刚开始赢得开发人员青睐的新手。 在这篇博文中࿰…...

39.3K Star,一个现代的数据库ORM工具,专为Node.js和TypeScript设计
大家好,今天给大家分享一个现代的数据库对象关系映射(Object-Relational Mapping,ORM)工具Prisma ORM,它旨在简化数据库操作,提高开发效率,并确保类型安全。 项目介绍 Prisma ORM适用于各种需要…...

Nginx和Mysql的基础命令
1.安装nginx brew install nginx 2.启动nginx brew services start nginx 3.查看nginx文件默认路径 brew info nginx 重装要先关闭nginx 4.nginx.conf 地址 nginx -t 5.nginx重启 brew services restart nginx 6.关闭nginx brew services stop nginx 7.卸载nginx brew uninstal…...

Docker之容器常见操作
docker 命令介绍 docker --help 管理命令: container 管理容器image 管理镜像network 管理网络命令: attach 介入到一个正在运行的容器build 根据 Dockerfile 构建一个镜像commit 根据容器的更改创建一个新的镜像cp 在本地文…...

猜数游戏(Fortran)
背景 学了两个月Fortran还没来一次正式练习 于是—— 代码 program gessnum! implicit none 不取消IN规则。integer::num,areal::Ncall random_seed()call random_number(N)aint(N*10)print*,"请输入您猜的数字:"read(*,*)numdo i1,3if (numa)thenpri…...

代码随想录 -- 贪心 -- 单调递增的数字
738. 单调递增的数字 - 力扣(LeetCode) 思路: 首先将正数n转化为字符串类型;定义一个flag:标记flag以及之后的位数都是9;从后向前遍历字符串n,如果当前的位数小于他上一位,将上一位…...

【小洛的VLOG】Web 服务器高并发压力测试(Reactor模型测试)
目录 引言 工具介绍 环境介绍 测试结果 个人主页:东洛的克莱斯韦克-CSDN博客 引言 大部分的网络通信都是支持TCP/IP协议栈,为了保证通信的可靠性,客户端和服务端之间需要建立链接。服务端能并发处理多少个链接,平均每秒钟能处理…...

Window:下载与安装triton==2.0.0
triton2.0.0谷仓下载 创建python3.10的工作环境: conda create -n anti-dreambooth python3.10然后在下载目录下执行代码: pip install triton-2.0.0-cp310-cp310-win_amd64.whl...

零,报错日志 2002-Can‘t connect to server on‘106.54.209.77‘(1006x)
零,报错日志 2002-Can’t connect to server on’106.54.209.77’(1006x) 今天差点被这个报错给折磨疯掉 尝试一:对腾讯云服务器进行更改 尝试二:针对配置文件处理 step1 //确保注释 /etc/mysql/mysql.conf.d/mysqld.cnf 下# bind-addres…...

R语言笔记(一)
文章目录 一、R objects二、Types of data三、Operators1、Operators2、Comparison operators3、Logical operators 四、Check types of data objects五、Convertion between data objects六、R workspace 一、R objects Two basic types of things/objects: data and functio…...

MusePose模型部署指南
一、模型介绍 MusePose是一个基于扩散和姿势引导的虚拟人视频生成框架。 主要贡献可以概括如下: 发布的模型能够根据给定的姿势序列,生成参考图中人物的舞蹈视频,生成的结果质量超越了同一主题中几乎所有当前开源的模型。发布该 pose alig…...