数组01-二分查找算法

目录

数组如何实现随机访问

两个关键词

数组的特点

根据下标随机访问数组元素

为什么数组要从0开始编号,而不是从1开始

LeetCode之路——704. 二分查找

Code

二分查找算法


数组如何实现随机访问

数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

两个关键词
  1. 第一是线性表(Linear List)。顾名思义,线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构。

  2. 第二个是连续的内存空间和相同类型的数据。正是因为这两个限制,它才有了一个堪称“杀手锏”的特性:“随机访问”。但有利就有弊,这两个限制也让数组的很多 操作变得非常低效,比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。

数组的特点
  1. 相同数据类型:数组中的所有元素必须是相同的数据类型,例如整数、浮点数、字符等。这是因为数组在内存中以相同大小的块存储每个元素,因此元素的数据类型必须一致。

  2. 固定大小:数组在创建时通常具有固定的大小,这意味着一旦数组的大小确定,就不能轻易改变。如果需要更多或更少的存储空间,通常需要创建一个新的数组。

  3. 连续存储:数组中的元素在内存中是连续存储的,这使得随机访问非常高效,因为可以通过计算索引位置直接访问元素,而不需要遍历整个数据结构。

  4. 零基索引:大多数编程语言中,数组的索引从零开始,这意味着第一个元素的索引为0,第二个元素的索引为1,以此类推。

  5. 随机访问:由于数组中的元素是连续存储的,可以通过索引来快速访问任何元素,这使得数组成为实现随机访问的理想数据结构。

  6. 固定存储开销:数组的存储开销是固定的,与数组的大小无关。这意味着如果数组的大小为n,那么它的存储开销也为n个元素的大小。

根据下标随机访问数组元素

我们用一个长度为10的int类型的数组int[] a = new int[10]来举例。i数组a[10]的大小为10,计算机给分配了一块连续的内存空间1000-1039,这块内存的首地址是base_address=1000.

计算机访问内存中的数据时通过内存单元分配的地址,寻址公式:

a[i]_address = base_address + i * data_type_size

其中data_type_size表示数组中每个元素的大小。我们举的这个例子里,数组中存储的是int类型数据,所以data_type_size就为4个字节。

为什么数组要从0开始编号,而不是从1开始

从数组存储的内存模型上来看,“下标”最确切的定义应该是“偏移(offset)”。前面也讲到,如果用a来表示数组的首地址,a[0]就是偏移为0的位置,也就是首地 址,a[k]就表示偏移k个type_size的位置,所以计算a[k]的内存地址只需要用这个公式:

a[k]_address = base_address + k * type_size

但是,如果数组从1开始计数,那我们计算数组元素a[k]的内存地址就会变为:

a[k]_address = base_address + (k-1)*type_size

对比两个公式,我们不难发现,从1开始编号,每次随机访问数组元素都多了一次减法运算,对于CPU来说,就是多了一次减法指令。 数组作为非常基础的数据结构,通过下标随机访问数组元素又是其非常基础的编程操作,效率的优化就要尽可能做到极致。所以为了减少一次减法操作,数组选 择了从0开始编号,而不是从1开始。

LeetCode之路——704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9     
输出: 4       
解释: 9 出现在 nums 中并且下标为 4     

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2     
输出: -1        
解释: 2 不存在 nums 中因此返回 -1     

提示:

  • 你可以假设 nums 中的所有元素是不重复的。

  • n 将在 [1, 10000]之间。

  • nums 的每个元素都将在 [-9999, 9999]之间。

分析:

  1. 有序数组、数组中无重复元素 ——> 二分查找算法

  2. 特殊场景:

    • n=1

    • target<nums[0]或者target>nums[n-1]

Code
class Solution {public int search(int[] nums, int target) {// 有序数组,元素不重复 ——> 二分查找算法int result = -1;// 特殊场景:target < nums[0] 或者 target > nums[n-1]int left = 0;int right = nums.length - 1;if (target < nums[left] || target > nums[right]) {return result;}while (left <= right) {int middle = left + ((right - left) >> 1);if (target < nums[middle]) {right = middle - 1;} else if (target > nums[middle]){left = middle + 1;} else {return middle;}}return result;}
}
二分查找算法

二分查找算法(Binary Search)是一种用于在有序数组中查找特定元素的高效搜索算法。它的工作原理是将数组分成两半,并比较中间元素与目标元素的大小关系,然后根据比较的结果决定继续在左半部分或右半部分继续查找,以此类推,直到找到目标元素或确定目标元素不存在为止。

以下是二分查找的基本步骤:

  1. 确定搜索范围的起始点(通常为数组的第一个元素)和结束点(通常为数组的最后一个元素)。

  2. 计算中间元素的索引:(起始点 + 结束点) / 2。如果是整数除法,向下取整。

  3. 比较中间元素与目标元素的值:

    • 如果中间元素等于目标元素,查找成功,返回中间元素的索引。

    • 如果中间元素大于目标元素,说明目标元素可能在左半部分,将结束点更新为中间元素的前一个位置。

    • 如果中间元素小于目标元素,说明目标元素可能在右半部分,将起始点更新为中间元素的后一个位置。

  4. 重复步骤2和步骤3,直到找到目标元素或搜索范围为空(起始点大于结束点),此时目标元素不存在于数组中。

二分查找是一种高效的算法,其时间复杂度为 O(log n),其中 n 是数组的大小。

参考资料:程序员Carl 代码随想录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142437.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C语言——运算符

C用运算符表示算术运算。 C没有指数运算符&#xff0c;不过&#xff0c;C的标准数学库提供了一个pow()函数用于指数运算。 基本运算符 赋值运算符&#xff1a; 变量名变量值 从右到左 左值和变量名的区别&#xff1a; 变量名是一个标识符的名称&#xff0c;左值是一个可变…

利用EasyX图形库实现趣味化编程note1

学习太久枯燥乏味&#xff1f;学习完Easyx图形库&#xff0c;创造无限可能。 首先来讲一下什么是图形库&#xff0c;图形库在屏幕上渲染图像的程序库&#xff0c;为我们提供了一组函数进行渲染&#xff0c;常见的图形库有QT,GTK,Windows GDI&#xff0c;著名的WPS就是用QT图形库…

视频汇聚/安防监控平台EasyCVR指定到新的硬盘进行存储录像,如何自动挂载该磁盘?

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

多线程的死锁问题

可重入和不可重入&#x1f60a;&#x1f60a;&#x1f60a; 一个线程针对同一个对象,连续加锁两次,是否会有问题 ~~ 如果没问题,就叫可重入的.如果有问题,就叫不可重入的. 代码示例&#x1f349;&#x1f349;&#x1f349;: synchronized public void add(){synchronized (…

大模型助力企业数据驱动,火山引擎数智平台发布AI助手

9月19日&#xff0c;火山引擎在其举办的“V-Tech数据驱动科技峰会”上宣布&#xff0c;火山引擎数智平台VeDI推出“AI助手”&#xff0c;通过接入人工智能大模型&#xff0c;帮助企业提升数据处理和查询分析的效率。即使是不会写代码的运营人员&#xff0c;和大模型对话也能做好…

【CNN-FPGA开源项目解析】卷积层03--单格乘加运算单元PE 单窗口卷积块CU 模块

03–单格乘加运算单元PE & 单窗口卷积块CU 文章目录 03--单格乘加运算单元PE & 单窗口卷积块CU前言单格乘加运算单元PE代码模块结构时序逻辑分析对其上层模块CU的要求 单窗口卷积块CU代码逻辑分析 前言 ​ 第一和第二篇日志已经详细阐述了"半精度浮点数"的加…

贪心算法-

代码随想录 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&#xff0c;你可以拿走十张&#xff0c;如果想达到最大的金额&#xff0c;你要怎么拿&#xff…

通过 HelpLook ChatBot AI自动问答机器人降低客户服务成本

在当今竞争激烈的商业环境中&#xff0c;提供卓越的客户服务对于维持忠诚的客户群和推动业务增长至关重要。客户服务涵盖了公司与其客户之间的所有互动&#xff0c;包括解答问题、解决问题和提供支持。它在塑造客户对品牌的看法方面起着关键作用&#xff0c;并且可以显著影响他…

如何通过bat批处理实现快速生成文件目录,一键生成文件名和文件夹名目录

碰对了情人&#xff0c;相思一辈子。 具体方法步骤&#xff1a; 一、创建一个执行bat文件&#xff08;使用记事本即可&#xff09;&#xff1b; 1、新建一个txt文本空白记事本文件 2、复制以下内容进记事本内 dir/a/s/b>LIST.TXT &#xff08;其中LIST.TXT文件名是提取后将…

【微服务】spring 控制bean加载顺序使用详解

目录 一、前言 二、使用order注解控制顺序 2.1 order 注解使用示例 2.2 order注解顺序失效问题 2.2.1 order失效问题解决办法 2.3 实现Ordered接口 三、使用dependon注解控制顺序 四、AutoConfiguration注解控制bean加载顺序 4.1 AutoConfigureBefore 操作演示 4.2 A…

安防视频平台EasyCVR视频调阅全屏播放显示异常是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

AIRIOT亮相IOTE2023深圳物联网展,产品创新力再获“IOTE金奖”

9月20-22日&#xff0c;IOTE 2023第二十届深圳国际物联网展在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为物联网领域年度最重要的行业盛会之一&#xff0c;本届展会以“IoT构建数字经济底座”为主题&#xff0c;汇聚全球来自工业、物流、基建、智慧城市、智慧…

freemarker自定义模板

模板编程器指南 <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version> </dependency>freemarker官网参考&#xff1a; https://freemarker.apache.org/docs/pgui_qu…

浏览器原生JavaScript离线文字转语音TTS播放,支持Windows自带TTS语音和移动端(安卓、IOS)

前言 JS已经可以实现语音合成(文字转语音)和语音识别(语音转文字),各个浏览器支持列表如下所示: 语音识别支持列表: 因此,浏览器上面使用语音合成非常简单。 页面效果示例: 实现功能 1、支持速度,音调设置 2、支持下拉选择语音模板 3、文字转语音 代码实现 …

云服务器 CentOS7 操作系统上安装Jpress (Tomcat 部署项目)

1、xShell 和 xftp 下载安装&#xff08;略&#xff09; https://www.xshell.com/zh/free-for-home-school/2、xftp 连接云服务器 xftp 新建连接 3、JDK 压缩包下载 下载 jdk1.8 注&#xff1a;此处 CentOS7 是64位&#xff0c;所以下载的是&#xff1a;Linux x64&#xf…

Hbuilder本地调试微信H5项目(二)--添加UView框架插件

摘要 在一个已创建的Hbuilder项目中&#xff0c;添加uView框架插件 前置准备 已安装Hbuilder 已创建uni-app的H5默认模板项目 实现逻辑 在Hbuilder官网找到组件说明页面 下载插件并导入HbuilderX 具体实现 访问网站 访问网址Hbuilder的uView1.8.6版本说明页 或者访问…

Python3操作MySQL8.XX创建表|CRUD基本操作

Python3操作MySQL8.XX创建表|CRUD基本操作 Python3操作SQLite3创建表主键自增长|CRUD基本操作 一&#xff1a; Python3操作Mysql数据库建表 import pymysqlPython3操作Mysql创建表&#xff1a; # 打开数据库连接 db pymysql.connect(host"localhost", user"您…

芯片SoC设计你了解吗?

数字IC设计根据岗位性质一般包含SOC设计&#xff0c;前端设计&#xff0c;ASIC设计&#xff0c;逻辑设计&#xff0c;IP设计&#xff0c;CPU设计等。 有人说&#xff1a;做IP设计就是翻译官&#xff0c;做SOC设计就是连连看。 SoC设计是做什么的&#xff1f;与IP设计有什么不同…

现代架构设计:构建可伸缩、高性能的分布式系统

文章目录 第1节&#xff1a;引言第2节&#xff1a;架构设计的关键原则2.1 微服务架构2.2 异步通信2.3 数据分区和复制2.4 负载均衡 第3节&#xff1a;代码示例3.1 创建产品服务3.2 创建消息队列3.3 创建产品更新服务 第4节&#xff1a;性能优化和监控4.1 建立性能基准4.2 水平扩…

解密智能化评估在培训考试系统中的应用

智能化评估在培训考试系统中的应用旨在提供更全面和准确的评估方式&#xff0c;以帮助培训机构或个人评估学员的学习成果。该系统结合了现代技术和评估理论&#xff0c;能够自动化地进行评估、反馈和分析&#xff0c;提供个性化的学习支持和指导。 智能化评估系统通过采集学员…