数组01-二分查找算法

news2024/11/19 23:25:50

目录

数组如何实现随机访问

两个关键词

数组的特点

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

为什么数组要从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.coloradmin.cn/o/1039295.html

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

相关文章

【从0学习Solidity】51. ERC4626 代币化金库标准

【从0学习Solidity】51. ERC4626 代币化金库标准 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#…

https跳过SSL认证时是不是就是不加密的,相当于http?

https跳过SSL认证时是不是就是不加密的,相当于http?&#xff0c;其实不是&#xff0c;HTTPS跳过SSL认证并不相当于HTTP&#xff0c;也不意味着没有加密。请注意以下几点&#xff1a; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;本质上是在HTTP的基础上…

在docker中删除none镜像

在构建过Docker镜像的电脑上查看本地镜像列表&#xff0c;有可能看到下图红框中的镜像&#xff0c;在列表中展示为:&#xff1a; 这种镜像在Docker官方文档中被称作dangling images&#xff0c;指的是没有标签并且没有被容器使用的镜像。 官方解释 来自官方的解释如下图红框所…

【多线程初阶】多线程案例之阻塞式队列

文章目录 前言1. 什么是阻塞队列2. 生产者消费者模型2.1 生产者消费者模型的优势2.1.1 解耦合2.1.2 削峰填谷 3. Java 标准库中的阻塞队列3.1 生产者消费者模型 4. 自己实现一个阻塞队列总结 前言 本文主要给大家讲解多线程的一个重要案例 — 阻塞式队列. 关注收藏, 开始学习…

如何在Windows11上使用macOS Sonoma全新的慢镜屏幕保护程序

前言 macOS Sonoma是Apple macOS一个大版本的描述&#xff0c;以任何方式使用macOS Sonoma都应确保符合Apple的规定 本文假定你在搭载Intel处理器的Apple产品上通过bootcamp安装了Windows11&#xff0c;且想要让Windows11产生类似于macOS Sonoma全新的慢镜屏幕保护程序的相关…

java面试题-jvm基础知识

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&a…

【记录文】Android自定义Dialog实现圆角对话框

圆角的dialog还是蛮常用的&#xff0c;demo中正好用上了 自定义Dialog&#xff0c;代码中可以设置指定大小与位置 /*** author : jiangxue* date : 2023/9/25 13:21* description :圆角的矩形*/internal class RoundCornerView(context: Context,view: Int, StyleRes theme…

智能网联驾驶测试与评价工业和信息化部重点实验室“车载智能计算基础平台参考架构2.0专家研讨会”圆满结束

近日&#xff0c;智能网联驾驶测试与评价工业和信息化部重点实验室在北京市召开“车载智能计算基础平台参考架构2.0专家研讨会”&#xff0c;本次会议由智能网联驾驶测试与评价工业和信息化部重点实验室、中国软件评测中心&#xff08;工业和信息化部软件与集成电路促进中心&am…

美颜SDK哪家好?2023美颜SDK有哪些新玩法?

在当今的数字世界中&#xff0c;美颜SDK正成为一种强大的工具&#xff0c;可以帮助我们在视频直播和短视频中展现出最美的自己。美摄科技作为一家专注于美颜SDK技术的公司&#xff0c;提供了多种领先的美颜SDK相关产品&#xff0c;以满足不同用户的需求。 美摄科技的美颜SDK是一…

第一章 计算机网络与协议

文章目录 一、计算机网络的基础概念二、计算机网络分类2.1 通信子网/资源子网/网络协议2.2 网络拓补图分类2.3 按照覆盖范围分类2.4 按照交换技术分类2.5 其他分类 三、OSI参考模型3.1 应用层3.2 表示层3.3 会话层3.4 传输层3.5 网络层3.6 数据链路层3.7 物理层3.8 借助OSI模型…

众佰诚:现在开一家抖音小店还来得及吗

随着互联网的迅猛发展&#xff0c;电商行业也进入了一个全新的时代&#xff0c;其中抖音小店作为新兴的销售平台备受瞩目。然而&#xff0c;对于那些考虑开设抖音小店的人来说&#xff0c;一个重要的问题是&#xff1a;现在开一家抖音小店还来得及吗? 答案是肯定的&#xff0c…

Vulnhub-DC-8 靶机复现完整过程

Vulnhub-DC-8 靶机复现完整过程 一、环境搭建 kali的IP地址&#xff1a;192.168.200.14 DC-8的IP地址&#xff1a;192.168.200.13&#xff08;一个flag&#xff09; 靶机和攻击机处于同一个网络方式&#xff1a;nat或桥接 若出现开机错误&#xff0c;适当将dc的兼容版本改低…

纷享销客荣获“最佳用户支持与服务奖”

近日&#xff0c;e签宝第二届用户生态峰会在上海如约而至。纷享销客作为e签宝生态合作伙伴&#xff0c;荣获“最佳用户支持与服务奖”。 数字化时代&#xff0c;孤岛式、断裂式、封闭式的数字化&#xff0c;不仅无法为客户带来价值&#xff0c;对提供数字化服务的双方而言&…

latex subsection 第一段 首行取消缩进

需求&#xff1a;在\subsection 标题下的第一段&#xff0c;取消首行缩进。 &#xff08;此时直接使用 \noindent 命令&#xff0c;失效&#xff09; 环境&#xff1a;IEEE 模板 解决方案&#xff1a; 增加一个空行&#xff0c;使有效内容行变为第二行&#xff0c;然后对其…

SQLAlchemy常用数据类型

目录 SQLAlchemy常用数据类型 代码演示 代码分析 SQLAlchemy常用数据类型 SQLAlchemy 是一个Python的SQL工具库和对象关系映射(ORM)工具&#xff0c;它提供了一种在Python中操作数据库的高效方式。下面是SQLAlchemy中常用的一些数据类型&#xff1a; Integer&#xff1a;整形&…

体验亚马逊的 CodeWhisperer 感觉

CodeWhisperer 是亚马逊推出的辅助编程工具&#xff0c;在程序员写代码时&#xff0c;它能根据其内容生成多种代码建议。 CodeWhisperer 目前已支持近10几种语言&#xff0c;我是用 java 语言&#xff0c;用的开发工具是 idea&#xff0c;说一下我用的情况。 亚马逊云科技开发…

四川玖璨电子商务有限公司正规吗?

​近年来&#xff0c;随着社交平台的兴起&#xff0c;带货已经成为了一种新型商业模式。抖音作为中国最大的短视频平台之一&#xff0c;也成为了众多商家进行带货销售的重要渠道。而在这个过程中&#xff0c;公司如四川玖璨电子商务有限公司也逐渐涌现出来&#xff0c;为广大用…

什么是 Redis?

Redis 是一种基于内存的数据库&#xff0c;对数据的读写操作都是在内存中完成的&#xff0c;因此读写速度非常快&#xff0c;常用于缓存&#xff0c;消息队列&#xff0c;分布式锁等场景。 Redis 提供了多种数据类型来支持不同的业务场景&#xff0c;比如 String(字符串)、Has…

Spring源码解析—— IOC默认标签解析(下)

正文 在上一篇我们已经完成了从xml配置文件到BeanDefinition的转换&#xff0c;转换后的实例是GenericBeanDefinition的实例。本文主要来看看标签解析剩余部分及BeanDefinition的注册。 默认标签中的自定义标签解析 在上篇博文中我们已经分析了对于默认标签的解析&#xff0…

vue 组件通信

vue 组件通信 mytitile 是变量 title 是形参 回调函数