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

01--二分查找

一. 初识算法

1.1 什么是算法?

在数学和计算机科学领域,算法是一系列有限的严谨指令,通常用于解决一类特定问题或执行计算

不正式的说,算法就是任何定义优良的计算过程:接收一些值作为输入,在有限的时间内,产生一些值作为输出。

1.2 什么是数据结构?

在计算机科学领域,数据结构是一种数据组织、管理和存储格式,通常被选择用来高效访问数据

数据结构是一种存储和组织数据的方式,旨在便于访问和修改

1.3 衡量算法好坏

一般从以下维度来评估算法的优劣:正确性、可读性、健壮性(对不合理输入的反应能力和处理能力)。
时间复杂度(time complexity):估算程序指令的执行次数(执行时间)。
空间复杂度(space complexity):估算所需占用的存储空间。

1.3.1 时间复杂度

常见的时间复杂度从快到慢:

常数复杂度                                 O(1)

对数复杂度                                 O(logn)

线性时间复杂度                          O(n)

线性对数复杂度                          O(nlogn)

平方                                            O(n^{2})

立方                                            O(n^{3})

指数                                            O(2^{n})

阶乘                                            O(n!)

1.3.2 空间复杂度

空间复杂度就是算法需要多少内存,占用了多少空间

常用的空间复杂度有O(1)、O(n)、O(n^{2})

二、二分查找

二分查找算法也称折半查找,是一种非常高效的工作于有序数组的查找算法。

2.1 二分查找基础版

	/*** @description: 二分查找基础版* @author: 憨憨浩浩* @date: 2023/12/11 21:54* @param: [a, target]* @return: int**/public static int binarySearchBasic(int[] a, int target) {// 定义左侧指针int i = 0;// 定义右侧指针int j = a.length - 1;// 当 i > j 时退出循环while (i <= j){// 定义中间指针int m = (i + j) / 2;if (a[m] > target){     // 目标值在左边j = m - 1;}else if (a[m] < target){       // 目标值在右边i = m + 1;}else {     // 找到目标值返回对应索引return m;}}return -1;      // 找不到目标值返回-1}

(i + j) / 2 有没有问题?

有问题,当数组长度足够长是会发生问题;

	@Testpublic void Test01(){int i = Integer.MAX_VALUE / 2;int j = Integer.MAX_VALUE;int m = (i + j) / 2;System.out.println(m);		// -536870913}

解决方案:

	@Testpublic void Test02(){int i = Integer.MAX_VALUE / 2;int j = Integer.MAX_VALUE;int m = (i + j) >>> 2;System.out.println(m);		// 805306367}

2.2 二分查找改变版

另一种写法

	/*** @description: 二分查找改变版* @author: 憨憨浩浩* @date: 2023/12/11 22:10* @param: [a, target]* @return: int**/public static int binarySearchAlternative(int[] a,int target){// 定义左侧指针int i = 0;// 定义右侧指针int j = a.length;// 当 i = j 时退出循环while (i < j){// 定义中间指针int m = (i + j) /2;if (a[m] > target){     // 目标值在左边j = m;} else if (a[m] < target) {     // 目标值在右边i = m + 1;}else {     // 找到目标值返回对应索引return m;}}return -1;      // 找不到目标值返回-1}

2.3 二分查找性能

2.4 二分查找平衡版

	/*** @description: 二分查找平衡版* @author: 憨憨浩浩* @date: 2023/12/13 13:46* @param: [a, target]* @return: int**/public static int binarySearchBalance(int[] a,int target){// 定义左侧指针int i = 0;// 定义右侧指针int j = a.length;// 当 i + 1 > j 时退出循环while (1 < j - i) {// 定义中间指针int m = (i + j) >>> 1;if (target < a[m]) {     // 目标值在左边j = m;} else {i = m;}}// 查到返回i,查不到返回-1return (a[i] == target) ? i : -1;}

2.5 二分查找 Java 版

Java8源码:

public static int binarySearch(int[] a, int key) {return binarySearch0(a, 0, a.length, key);}private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {int low = fromIndex;int high = toIndex - 1;while (low <= high) {int mid = (low + high) >>> 1;int midVal = a[mid];if (midVal < key)low = mid + 1;else if (midVal > key)high = mid - 1;elsereturn mid; // key found}return -(low + 1);  // key not found.}

2.6 Leftmost 与 Rightmost

	/*** @description: 二分查找返回左侧的索引值* @author: 憨憨浩浩* @date: 2023/12/15 20:21* @param: [a, target]* @return: int**/public static int binarySearchLeftmost1(int[] a,int target){int i = 0, j = a.length - 1;int candidate = -1;while (i <= j) {int m = (i + j) >>> 1;if (target < a[m]) {j = m - 1;} else if (a[m] < target) {i = m + 1;} else {candidate = m; // 记录候选位置j = m - 1;     // 继续向左}}return candidate;}

如果希望返回的是最右侧元素

	/*** @description: 二分查找返回最右侧值的索引* @author: 憨憨浩浩* @date: 2023/12/15 20:23* @param: [a, target]* @return: int**/public static int binarySearchRightmost1(int[] a,int target){int i = 0, j = a.length - 1;int candidate = -1;while (i <= j) {int m = (i + j) >>> 1;if (target < a[m]) {j = m - 1;} else if (a[m] < target) {i = m + 1;} else {candidate = m; // 记录候选位置i = m + 1;	   // 继续向右}}return candidate;}

应用

对于 Leftmost 与 Rightmost,可以返回一个比 -1 更有用的值

Leftmost 改为

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

Rightmost 改为

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

大于等于中间值,都要向右找

几个名词

 

相关文章:

01--二分查找

一. 初识算法 1.1 什么是算法&#xff1f; 在数学和计算机科学领域&#xff0c;算法是一系列有限的严谨指令&#xff0c;通常用于解决一类特定问题或执行计算 不正式的说&#xff0c;算法就是任何定义优良的计算过程&#xff1a;接收一些值作为输入&#xff0c;在有限的时间…...

初识大数据应用,一文掌握大数据知识文集(1)

文章目录 &#x1f3c6;初识大数据应用知识&#x1f50e;一、初识大数据应用知识(1)&#x1f341; 01、请用Java实现非递归二分查询&#xff1f;&#x1f341; 02、是客户端还是Namenode决定输入的分片&#xff1f;&#x1f341; 03、mapred.job.tracker命令的作用&#xff1f;…...

Kafka生产问题总结及性能优化实践

1、消息丢失情况 消息发送端&#xff1a; &#xff08;1&#xff09;acks0&#xff1a; 表示producer不需要等待任何broker确认收到消息的回复&#xff0c;就可以继续发送下一条消息。性能最高&#xff0c;但是最容易丢消息。大数据统计报表场景&#xff0c;对性能要求很高&am…...

[MySQL]数据库原理2,Server,DataBase,Connection,latin1、UTF-8,gb2312,Encoding,Default Collation——喵喵期末不挂科

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…...

【算法集训】基础数据结构:十、矩阵

矩阵其实就是二维数组&#xff0c;这些题目在9日集训中已经做过&#xff0c;这里做的方法大致相同。 第一题 1351. 统计有序矩阵中的负数 int countNegatives(int** grid, int gridSize, int* gridColSize) {int r gridSize;int c gridColSize[0];int ret 0;for(int i 0;…...

python排序算法 直接插入排序法和折半插入排序法

最近需要使用到一些排序算法&#xff0c;今天主要使针对直接插入排序和折半插入排序进行讲解。 首先是直接插入排序&#xff0c;其排序过程主要是&#xff0c;针对A[a1,a2,a3,a4,a5....an]&#xff0c;从排序的序列头部起始位置开始&#xff0c;将其也就是a1视为只有一个元素的…...

【flutter对抗】blutter使用+ACTF习题

最新的能很好反编译flutter程序的项目 1、安装 git clone https://github.com/worawit/blutter --depth1 然后我直接将对应的两个压缩包下载下来&#xff08;通过浏览器手动下载&#xff09; 不再通过python的代码来下载&#xff0c;之前一直卡在这个地方。 如果读者可以正…...

OpenHarmony 如何去除系统锁屏应用

前言 OpenHarmony源码版本&#xff1a;4.0release / 3.2 release 开发板&#xff1a;DAYU / rk3568 一、3.2版本去除锁屏应用 在源码根目录下&#xff1a;productdefine/common/inherit/rich.json 中删除screenlock_mgr组件的编译配置&#xff0c;在rich.json文件中搜索th…...

Python - 搭建 Flask 服务实现图像、视频修复需求

目录 一.引言 二.服务构建 1.主函数 upload_gif 2.文件接收 3.专属目录 4.图像修复 5.gif2mp4 6.mp42gif 7.图像返回 三.服务测试 1.服务启动 2.服务调用 四.总结 一.引言 前面我们介绍了如何使用 Real-ESRGAN 进行图像增强并在原始格式 jpeg、jpg、mp4 的基础上…...

C#基础——构造函数、析构函数

C#基础——构造函数、析构函数 1、构造函数 构造函数是一种特殊的方法&#xff0c;用于在创建类的实例时进行初始化操作。构造函数与类同名&#xff0c;并且没有返回类型。 构造函数在对象创建时自动调用&#xff0c;可以用来设置对象的初始状态、分配内存、初始化字段等操作…...

jmeter 如何循环使用接口返回的多值?

有同学在用jmeter做接口测试的时候&#xff0c;经常会遇到这样一种情况&#xff1a; 就是一个接口请求返回了多个值&#xff0c;然后下一个接口想循环使用前一个接口的返回值。 这种要怎么做呢&#xff1f; 有一定基础的人&#xff0c;可能第一反应就是先提取前一个接口返回…...

VLAN 详解一(VLAN 基本原理及 VLAN 划分原则)

VLAN 详解一&#xff08;VLAN 基本原理及 VLAN 划分原则&#xff09; 在早期的交换网络中&#xff0c;网络中只有 PC、终端和交换机&#xff0c;当某台主机发送一个广播帧或未知单播帧时&#xff0c;该数据帧会被泛洪&#xff0c;甚至传递到整个广播域。而广播域越大&#xff…...

Android - 分区存储 MediaStore、SAF

官方页面 参考文章 一、概念 分区存储&#xff08;Scoped Storage&#xff09;的推出是针对 APP 访问外部存储的行为&#xff08;乱建乱获取文件和文件夹&#xff09;进行规范和限制&#xff0c;以减少混乱使得用户能更好的控制自己的文件。 公有目录被分为两大类&#xff1a;…...

Shiro框架权限控制

首先去通过配置类的用户认证&#xff0c;在用户认证完成后&#xff0c;进行用户授权&#xff0c;用户通过授权之后再跳转其他的界面时&#xff0c;会进行一个验证&#xff0c;当前账号是否有权限。 前端权限控制显示的原理 在前端中&#xff0c;通常使用用户的角色或权限信息来…...

centOS7 安装tailscale并启用子网路由

1、在centOS7上安装Tailscale客户端 #安装命令所在官网位置&#xff1a;https://tailscale.com/download/linux #具体命令为&#xff1a; curl -fsSL https://tailscale.com/install.sh | sh #命令执行后如下图所示2、设置允许IP转发和IP伪装。 安装后&#xff0c;您可以启动…...

spring 项目中如何处理跨越cors问题

1.使用 CrossOrigin 注解 作用于controller 方法上 示例如下 RestController RequestMapping("/account") public class AccountController {CrossOriginGetMapping("/{id}")public Account retrieve(PathVariable Long id) {// ...}DeleteMapping(&quo…...

importlib --- import 的实现

3.1 新版功能. 源代码 Lib/importlib/__init__.py 概述 importlib 包具有三重目标。 一是在 Python 源代码中提供 import 语句的实现&#xff08;并且因此而扩展 __import__() 函数&#xff09;。 这提供了一个可移植到任何 Python 解释器的 import 实现。 与使用 Python 以…...

【PyTorch】现代卷积神经网络

文章目录 1. 理论介绍1.1. 深度卷积神经网络&#xff08;AlexNet&#xff09;1.1.1. 概述1.1.2. 模型设计 1.2. 使用块的网络&#xff08;VGG&#xff09;1.3. 网络中的网络&#xff08;NiN&#xff09;1.4. 含并行连结的网络&#xff08;GoogLeNet&#xff09;1.5. 批量规范化…...

用python编写九九乘法表

1 问题 我们在学习一门语言的过程中&#xff0c;都会练习到编写九九乘法表这个代码&#xff0c;下面介绍如何编写九九乘法表的流程。 2 方法 &#xff08;1&#xff09;打开pycharm集成开发环境&#xff0c;创建一个python文件&#xff0c;并编写第一行代码&#xff0c;主要构建…...

Google Gemini 模型本地可视化

Google近期发布了Gemini模型&#xff0c;而且开放了Gemini Pro API&#xff0c;Gemini Pro 可免费使用&#xff01; Gemini Pro支持全球180个国家的38种语言&#xff0c;目前接受文本、图片作为输入并生成文本作为输出。 Gemini Pro的表现超越了其他同类模型&#xff0c;当前版…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...