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

【算法小课堂】二分查找算法

在这里插入图片描述

简单思路:

当我们要从一个序列中查找一个元素的时候,最快想到的方法就是顺序查找法(即:从前到后依次查找)。但这种方法过于无脑,就是暴力的把每个元素都排查一遍。元素个数少的时候还行,一旦元素个数多起来,效率是非常低下,所以在实际中这种查找的方法是被摒弃的。

当题目或者实际对时间复杂度有着很高的要求的时候,这种暴力解法就显得很乏力

这里就不得不介绍一种简单且效率较高的查找方法了:二分查找法,又称折半查找法。但该方法是建立在有序的前提下的,基本思路就是:

利用两个指针left和right,不断取中点来不断把区间减小从而找到我们的答案

二分查找法的优势:

  • 二分查找法的时间复杂度:O(logN)

  • 暴力解法的时间复杂度:O(N)

如何直观来体现二分查找法时间复杂度的优势呢?

img

可以看出 二分查找 在查找数字 37 时只需3次,而 顺序查找 在查找37时需要12次。

二分查找的条件:

很多算法书都是写的具有有序性,其实更准确的是具有二段性

  • 也就是具有可以把数组分为两端的性质

二分查找有两个限制条件:

  1. 查找的数量只能是一个,不能是多个
  2. 查找的对象在逻辑上必须是有序的(这个不是必要条件,更深层次是就有二段性)

朴素二分查找:

1.left=0,right=数组最后一个位置的下标

2.取中点:mid=(right-left)/2

二分法的思想很简单,因为整个数组是有序的,数组默认是递增的。

首先选择数组中间的数字和需要查找的目标值比较

  • 如果相等最好,就可以直接返回答案了

  • 如果不相等

    如果中间的数字大于目标值,则中间数字向右的所有数字都大于目标值,全部排除

    如果中间的数字小于目标值,则中间数字向左的所有数字都小于目标值,全部排除

704. 二分查找

以此题为例:

class Solution {
public:int search(vector<int>& nums, int target) {int left=0;int right=nums.size()-1;while(left<=right){int mid=left+(right-left)/2;if(nums[mid]==target) return mid;if(nums[mid]>target) right=mid-1;if(nums[mid]<target) left=mid+1;}return -1;}
};

朴素二分查找的模版:

        while(left<=right){int mid=left+(right-left)/2;if(nums[mid]==target) return mid;if(nums[mid]>target) ...;if(nums[mid]<target) ...;}return ...;

二分查找左右端点:

我们通过一个例子:

34. 在排序数组中查找元素的第一个和最后一个位置

本题我们利用二分来解决左右端点的问题,首先left和right肯定有的

我们通过一个示例来了解本题:[1,2,3,3,3,4,5]

查找左端点:我们这里用t来代替target(这样比较好叙述)

img

  • 二分的思路操作:我们可以将上述示例分为两个部分,因为我们现在查找左端点,因此我可以将示例分为【[1,2],[3,3,3,4,5]】

img

  1. 当x<t时,处于【1,2】这个区间,left=mid+1
  2. 当x>=t时,处于【3,3,3,4,5】这个区间,right=mid(这里不能等于mid-1,因为如果mid=0,right=-1会越界)
  • 细节处理:

循环条件:

  1. left<right
  2. left<=right ×

我们选择那种呢?我们来讨论一下:

img

  1. 有结果
  2. 全大于t(t1),right一直向左走,最后right为left结束,如果是left<=right会死循环
  3. 全小于t(t2),left一直向右走,最后left在right右边结束

以此我们只能选择第一种不能选择第二种!

求中间的操作:

  1. left+(right-left)/2 ×
  2. left+(right-left+1)/2

我们考虑一下极端情况就可以知道了!当只剩下两个元素的时候:

img
第一种没有问题,第二种mid=0+2/2=1,当进行left+1操作的时候会发生越界

查找右端点

  • 二分的思路操作:我们可以将上述示例分为两个部分,因为我们现在查找左端点,因此我可以将示例分为【[1,2,3,3,3].[4,5]】

img

  1. 当x<=t时,处于【1,2,3,3,3】这个区间,left=mid
  2. 当x>t时,处于【4,5】这个区间,right=mid-1
  • 细节处理:

循环条件:

  1. left<right
  2. left<=right ×

还是选择left<right

求中间的操作:

  1. left+(right-left)/2
  2. left+(right-left+1)/2 ×

我们考虑一下极端情况就可以知道了!当只剩下两个元素的时候:

img

第一种当mid=0+1/2=0时,right=mid-1越界,第二种没有问题

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {//特殊情况处理一下if(nums.size()==0)return {-1,-1};int left=0,right=nums.size()-1;vector<int> ret;//查找左端点while(left<right){int mid=left+(right-left)/2;if(nums[mid]<target)left=mid+1;if(nums[mid]>=target)right=mid;}//当left==right时就是结果if(nums[left]!=target)return {-1,-1};else ret.push_back(left);//查找右端点left=0,right=nums.size()-1;while(left<right){int mid=left+(right-left+1)/2;if(nums[mid]<=target)left=mid;if(nums[mid]>target)right=mid-1;}if(nums[right]!=target)return {-1,-1};else ret.push_back(right);return ret;}
};

查找区间左右端点的模版:

image-20231001143903966

模版,这里主要是取中间这里不太一样,左端点时不用+1,右端点+1(记忆当下面出现-1,上面就+1)

至于left和right可以现场推导

在这里插入图片描述

相关文章:

【算法小课堂】二分查找算法

简单思路&#xff1a; 当我们要从一个序列中查找一个元素的时候&#xff0c;最快想到的方法就是顺序查找法&#xff08;即&#xff1a;从前到后依次查找&#xff09;。但这种方法过于无脑&#xff0c;就是暴力的把每个元素都排查一遍。元素个数少的时候还行&#xff0c;一旦元…...

git修改提交历史中的author信息

全局设置 git config --global user.name "作者名" 局部设置(本项目) git config user.name "作者名" git修改提交作者和邮箱-CSDN博客 git修改提交作者和邮箱-CSDN博客...

【gitlab】本地项目上传gitlab

需求描述 解决方法 下面的截图是gitlab空项目的描述 上传一个本地项目按其中“Push an existing folder”命令即可。 以renren-fast项目为例 # 用git bash 下载renren-fast项目 git clone https://gitee.com/renrenio/renren-fast.git# 在renren-fast的所属目录 打开git ba…...

freertos信号量之计数信号量

freertos信号量之计数信号量 简介例程 简介 计数信号量&#xff08;Counting Semaphore&#xff09;用于管理共享资源的访问。以下是计数信号量的常用函数及其说明&#xff1a; 1&#xff09;xSemaphoreCreateCounting(unsignedportBASE_TYPE uxMaxCount, unsignedportBASE_T…...

wc命令使用指南 | 教你如何高效统计文件字数、行数和字符数

文章目录 wc命令使用指南1. 引言1.1 什么是wc命令&#xff1f;1.2 wc命令的作用和用途1.3 wc命令的常用参数 2. 基本使用2.1 安装和启动wc命令2.2 统计文件的行数2.3 统计文件的字数2.4 统计文件的字符数2.5 统计文件的词数2.6 统计文件的最长行长度 3. 高级使用3.1 统计多个文…...

网络安全:发起一次CSRF攻击!

一、如何发起一次CSRF攻击 原理&#xff1a;CSRF 的本质实际上是利用了 Cookie 会自动在请求中携带的特性&#xff0c;通过伪造请求来执行恶意操作。 1、目标网站信息&#xff1a; 接口地址&#xff1a;https://victim.com/change-password 请求类型&#xff1a;get/post 接…...

java上传文件到指定服务器

首先要知道服务器的用户名和密码。 注意&#xff1a;一般情况&#xff0c;如果不是强制要求&#xff0c;尽量不要将文件上传到服务器 步骤&#xff1a; 1.导入依赖 <!--图片上传到服务器需要的依赖--> <dependency> <groupId>com.jcr…...

揭秘 Go 中的 new() 和 make() 函数

Go&#xff08;或 Golang&#xff09;是一种现代、静态类型、编译型的编程语言&#xff0c;专为构建可扩展、并发和高效的软件而设计。它提供了各种内置的函数和特性&#xff0c;帮助开发人员编写简洁高效的代码。其中包括 new() 和 make() 函数&#xff0c;这两个函数乍看起来…...

【Spring Cloud】深入探索统一网关 Gateway 的搭建,断言工厂,过滤器工厂,全局过滤器以及跨域问题

文章目录 前言为什么需要网关以及网关的作用网关的技术实现 一、Gateway 网关的搭建1.1 创建 Gateway 模块1.2 引入依赖1.3 配置网关1.4 验证网关是否搭建成功1.5 微服务结构分析 二、Gateway 断言工厂2.1 Spring 提供的断言工厂2.2 示例&#xff1a;设置断言工厂 三、Gateway …...

计算机竞赛 题目:基于卷积神经网络的手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…...

关于flink重新提交任务,重复消费kafka的坑

异常现象1 按照以下方式设置backend目录和checkpoint目录&#xff0c;fsbackend目录有数据&#xff0c;checkpoint目录没数据 env.getCheckpointConfig().setCheckpointStorage(PropUtils.getValueStr(Constant.ENV_FLINK_CHECKPOINT_PATH)); env.setStateBackend(new FsStat…...

Win11右键恢复Win10老版本

Win11右键恢复Win10老版本 最近自己更新了windows11的OS,整体感觉都是不错的,但是就是每次右键菜单我都要再次点击下展开更多选项,这对追求极简主义的我,就是不爽, 手动恢复win10操作吧! 第一种:创建文件(简单快速) 1.新建一个resoreRightKey.reg文件,并在里面填入如下代码 W…...

ur机械臂30003端口socket通信踩坑(double类型数据怎么解析)

坑的由来 都知道在网络通信时要把网络字节序转化为主机字节序才行&#xff0c;但是c里的标准库函数ntohl默认是转换32位字节序的数据&#xff0c;也就是说默认是转换float类型的数据&#xff1b;而ur机械臂30003端口发送的是double类型的数据&#xff0c;没法直接用ntohl进行转…...

代理IP与Socks5代理的技术奇妙之旅

随着数字化时代的崛起&#xff0c;网络工程师们日益承担着维护网络稳定性和保护数据安全的重任。在这个充满挑战的世界里&#xff0c;代理IP与Socks5代理技术成为了他们的秘密武器&#xff0c;本文将带您踏上一段技术奇妙之旅&#xff0c;深入了解这两项技术在不同领域中的应用…...

自动化测试定位不到元素?可能是 frame 在搞鬼

很多人在用Splinter或Selenium定位页面元素的时候会遇到定位不到的问题&#xff0c;明明元素就在那儿&#xff0c;就是定位不到&#xff0c;这种情况很有可能是frame在搞鬼。 说白了就是网站上的网页A&#xff0c;又嵌入了其他网页B。你访问了网页A&#xff0c;在里面可以看到…...

uni-app 开发中,监听 input 键盘事件获取不到按下按键值怎么办?

uniapp 开发 H5 时&#xff0c;无法监听按钮键盘事件的原因以及解决方法。 问题描述&#xff1a; 不少 uni-app 开发者在使用 input 组件时&#xff0c;监听 keyup 事件时&#xff0c;获取不到键盘的 keyCode。编写的代码如下&#xff1a; <template><input keyup&…...

【juc】countdownlatch实现并发网络请求

目录 一、截图示例二、代码示例2.1 测试代码2.2 接口代码 一、截图示例 二、代码示例 2.1 测试代码 package com.learning.countdownlatch;import lombok.extern.slf4j.Slf4j; import org.springframework.web.client.RestTemplate;import java.util.Arrays; import java.uti…...

在供应链管理中,如何做好库存分析?库存分析有哪些监控指标?

在供应链管理中&#xff0c;库存分析是其重要的一环。库存分析的方法繁杂且广泛&#xff0c;选择正确的方法才能更好的进行库存分析&#xff0c;下面就为大家盘点一些常用的库存分析方法和监控指标&#xff0c;全程干货&#xff0c;建议收藏&#xff01; 01 如何进行库存分析&…...

黑豹程序员-架构师学习路线图-百科:Database数据库

文章目录 1、什么是Database2、发展历史3、数据库排行网4、总结 1、什么是Database 当今世界是一个充满着数据的互联网世界&#xff0c;各处都充斥着大量的数据。即这个互联网世界就是数据世界。 支撑这个数据世界的基石就是数据库&#xff0c;数据库也可以称为数据的仓库。 …...

你相信光吗?黑灯工厂重新相信“光”

你知道“黑灯工厂”吗&#xff1f;望文生义&#xff0c;所谓黑灯工厂&#xff0c;就是可以不需要照明的工厂。全程流水线自动化生产&#xff0c;无人干预、无人值守&#xff0c;工厂变成黑匣子&#xff0c;原材料进去&#xff0c;成品出来&#xff0c;流水线上百分百自动化。 完…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...