2023 跟我一起学算法:数据结构和算法-数组(下)

2023 跟我一起学算法:数据结构和算法-数组(下)

数组数据结构的应用:

  • 存储和访问数据:数组用于按特定顺序存储和检索数据。例如,数组可用于存储一组学生的分数,或气象站记录的温度。
  • 排序: 数组可用于按升序或降序对数据进行排序。冒泡排序、合并排序和快速排序等排序算法严重依赖数组。
  • 搜索:可以使用线性搜索和二分搜索等算法在数组中搜索特定元素。
  • 矩阵:数组用于表示数学计算中的矩阵,例如矩阵乘法、线性代数和图像处理。
  • 栈和队列: 数组作为底层数据结构来实现栈和队列,常用于算法和数据结构中。
  • :数组可用于表示计算机科学中的图。数组中的每个元素代表图中的一个节点,节点之间的关系由数组中存储的值表示。
  • 动态编程:动态编程算法通常使用数组来存储子问题的中间结果,以解决更大的问题。

数组的实时应用:

  • 信号处理: 数组在信号处理中用于表示随时间收集的一组样本。这可用于语音识别、图像处理和雷达系统等应用。
  • 多媒体应用: 数组用于多媒体应用,例如视频和音频处理,用于存储像素或音频样本。例如,可以使用数组来存储图像的 RGB 值。
  • 数据挖掘: 数组在数据挖掘应用程序中用于表示大型数据集。这可以实现高效的数据访问和处理,这在实时应用程序中非常重要。
  • 机器人技术:机器人技术中使用数组来表示 3D 空间中物体的位置和方向。这可用于运动规划和对象识别等应用。
  • 实时监控系统: 实时监控系统中使用阵列来存储传感器数据和控制信号。这可以实现实时处理和决策,这在工业自动化和航空航天系统等应用中非常重要。
  • 财务分析: 数组在财务分析中用于存储历史股票价格和其他财务数据。这可以实现高效的数据访问和分析,这在实时交易系统中非常重要。
  • 科学计算: 数组在科学计算中用于表示数值数据,例如实验和模拟的测量结果。这可以实现高效的数据处理和可视化,这对于实时科学分析和实验非常重要。

数组数据结构的优点:

  • 高效访问元素: 数组提供对集合中任何元素的直接高效访问。访问数组中的元素是一个 O(1) 操作,这意味着访问元素所需的时间是恒定的,并且不依赖于数组的大小。
  • 快速数据检索: 数组允许快速数据检索,因为数据存储在连续的内存位置中。这意味着可以快速有效地访问数据,而不需要复杂的数据结构或算法。
  • 内存效率: 数组是一种节省内存的数据存储方式。由于数组的元素存储在连续的内存位置中,因此数组的大小在编译时已知。这意味着可以在一个块中为整个数组分配内存,从而减少内存碎片。
  • 多功能性: 数组可用于存储多种数据类型,包括整数、浮点数、字符,甚至对象和指针等复杂的数据结构。
  • 易于实现: 数组易于实现和理解,使其成为初学者学习计算机编程的理想选择。
  • 与硬件的兼容性: 数组数据结构与大多数硬件架构兼容,使其成为在各种环境下进行编程的通用工具。

数组数据结构的缺点:

  • 固定大小: 数组具有在创建时确定的固定大小。这意味着,如果需要增加数组的大小,则必须创建一个新数组,并且必须将数据从旧数组复制到新数组,这可能非常耗时且占用内存。
  • 内存分配问题: 分配大型数组可能会出现问题,特别是在内存有限的系统中。如果数组的大小太大,系统可能会耗尽内存,从而导致程序崩溃。
  • 插入和删除问题:从数组中插入或删除元素可能效率低下且耗时,因为插入或删除点之后的所有元素都必须移动以适应更改。
  • 浪费的空间: 如果数组未完全填充,则为该数组分配的内存中可能会出现浪费的空间。如果内存有限,这可能是一个问题。
  • 有限的数据类型支持: 数组对复杂数据类型(例如对象和结构)的支持有限,因为数组的元素必须全部具有相同的数据类型。
  • 缺乏灵活性: 与链表和树等其他数据结构相比,固定大小和对复杂数据类型的有限支持可能使数组缺乏灵活性。

结构体相对于数组的优点:

  • 结构体可以存储不同类型的数据,而数组只能存储相似的数据类型。
  • 结构不像数组那样有大小限制。
  • 结构元素可能会也可能不会存储在连续位置,但数组元素会存储在连续位置。
  • 在结构中,可以实例化对象,而在数组中则不可能实例化对象。

使用数组的常见问题

  • 为什么从数组中获取值的复杂度是 O(1)?

    数组是一种线性数据结构。在数组中,获取值的操作需要常数时间,即 O(1)。由于数组在内存中连续分配,因此通过数组索引获取值是一种算术运算。所有算术运算都在恒定时间内完成,即O(1)

    第 i个索引的地址= 基址 + 偏移量 = 第 0个索引的地址 + i ×(一个元素的大小)

例子:

数组中的内存分配

在数组A[] = {8, 6, 7, 13, 8, 19}中

要获取索引 4 处的值,我们需要存储该索引值的内存地址。该地址可以通过进行算术运算来获得,即

索引 4 处的值的地址 = 索引 0 处的值的地址 + 4 × int的大小= 108 + 4 × 4 字节 索引 4 处的值的地址 = 124 A[4] = 地址 124 处的值 = 8

什么时候应该使用数组而不是列表?

  • 当我们需要多维结构来存储数据时,我们使用数组而不是列表,因为列表只能是一维的。
  • 如果我们需要固定长度和静态分配,则使用数组而不是列表。
  • 当需要更快地处理数据时,可以使用数组而不是列表。
  • 原始数据类型可以直接存储在数组中,但不能存储在列表中,因此,我们使用数组而不是列表。

在 Python 中使用数组而不是列表:

  • 我们在 python 中使用数组而不是列表,因为它需要更少的内存。
  • python 中数组比列表快。
  • 数组可以直接处理算术运算,而列表则不能。所以我们使用数组而不是列表。
  • 对于较长的数据项序列,数组优于列表。

算法练习

给定一个大小为N-1的数组arr[] ,其中整数在[1, N]范围内,任务是从前N个整数中找到丢失的数字。

注意:列表中没有重复项。

输入: arr[] = {1, 2, 4, 6, 3, 7, 8}, N = 8

输出: 5

解释: 1 到 8 之间缺少的数字是 5

go 复制代码
func findMissing(arr []int) int {
    var x = make([]int, len(arr)+1)
    for _, v := range arr {
        x[v-1] = 1
    }

    for index, v := range x {
        if v == 0 {
            return index + 1
        }
    }
    return -1
}

func findMissing2(arr []int) int {
    // 求前 n 项自然数的和
    l := len(arr) + 1
    totalSum := (l * (l + 1)) / 2
    var sum = 0
    for _, v := range arr {
            sum += v
    }
    return totalSum - sum
}

算法分析

  1. findMissing

    • findMissing 首先初始化一个 N 大小的数组,目的就占位
    • 将整数[1, N]的值-1 保存在初始化好的数组中对应的 index 位置上
    • 第二个循环的目的就是找到值为 0 的index,因为目标数组中缺少相应位置的 val
    • 最后就找到了确实的整数

复杂度分析:

  • 时间复杂度:我们使用两个 for循环, 循环的次数取决于 array 的大小 所以时间复杂度为 O(2N) , 2 为常量,所以复杂度为 O(N)
  • 空间复杂度:我们开始初始化了一个 N+1 长度的数组 x, 所以空间复杂度为 O(1)
  1. findMissing2

    • 算法的主要思想就是使用整数的前 N 项的和(n * (n + 1)) / 2 减去数组中所有数的和,就是缺失的整数

复杂度分析:

  • 时间复杂度:findMissing2 中我们使用了一个 for ,循环的次数取决于 array 的大小 所以时间复杂度为 O(N)
  • 空间复杂度:我们使用了两个变量 l 用来标记数组的长度和 totalSum 用来计算前 N 项的和。空间复杂度为 O(1)

相关文章

2023 跟我一起学算法:数据结构和算法-数组(上) - 掘金 (juejin.cn)

相关推荐
老葱头蒸鸡2 分钟前
(27)APS.NET Core8.0 堆栈原理通俗理解
算法
文心快码BaiduComate2 分钟前
用Zulu轻松搭建国庆旅行4行诗网站
前端·javascript·后端
视睿8 分钟前
【C++练习】06.输出100以内的所有素数
开发语言·c++·算法·机器人·无人机
草莓熊Lotso14 分钟前
从 “Hello AI” 到企业级应用:Spring AI 如何重塑 Java 生态的 AI 开发
java·人工智能·经验分享·后端·spring
Terio_my1 小时前
Spring Boot 整合 Elasticsearch
spring boot·后端·elasticsearch
柠檬07111 小时前
matlab cell 数据转换及记录
算法
行者..................1 小时前
手动编译 OpenCV 4.1.0 源码,生成 ARM64 动态库 (.so),然后在 Petalinux 中打包使用。
前端·webpack·node.js
YuTaoShao2 小时前
【LeetCode 每日一题】2221. 数组的三角和
数据结构·算法·leetcode
阑梦清川2 小时前
linux基础--文件描述符&&输出重定向的理解
后端