2023 跟我一起学算法:数据结构和算法-数组(上)
什么是数组?
数组是存储在连续内存位置的相同变量类型的项目的集合。它是最流行和最简单的数据结构之一,通常用于实现其他数据结构。数组中的每个项目都从 0 开始索引。
每个程序员的梦想不仅是成为一名优秀的程序员,而且成为一名伟大的程序员。我们都想实现我们的目标,为了实现我们的目标,我们必须有一个伟大的计划。
我们可以通过索引值直接访问数组元素。
数组的基本术语
- 数组索引: 在数组中,元素由其索引来标识。数组索引从0开始。
- 数组元素: 元素是存储在数组中的项目,可以通过其索引进行访问。
- 数组长度: 数组的长度由它可以包含的元素数量决定。
数组的表示
数组的表示可以通过其声明来定义。声明意味着为给定大小的数组分配内存。
数组可以用不同的语言以不同的方式声明。为了更好地说明,下面是一些特定于语言的数组声明。
然而,上面的声明是静态 或编译时 内存分配,这意味着数组元素的内存是在程序编译时分配的。这里只会分配固定大小(即方括号 [] 中提到的大小)的内存用于存储,但是我们不认为这不会与我们知道数组的大小相同的情况每次,可能会出现我们不知道数组大小的情况。如果我们声明较大的大小并存储较少数量的元素,将导致内存浪费,或者是我们声明较小的大小的情况,那么我们将不会获得足够的内存来存储其余元素。在这种情况下,静态内存分配不是首选。
为什么需要数组数据结构?
假设有一个班有五名学生,如果我们必须记录他们的考试成绩,我们可以通过声明五个变量并跟踪记录来做到这一点,但如果学生人数变得非常多,那会怎样?操纵和维护数据具有挑战性。
这意味着,当我们有少量对象时,我们可以使用普通变量(v1,v2,v3,..)。但如果我们想要存储大量实例,用普通变量来管理它们就变得很困难。数组的想法是在一个变量中表示许多实例..
数组类型:
数组主要有两种类型:
- 一维数组(1-D array) : 们可以将一维数组想象为一行,其中一个接一个地存储元素。
一维数组
- 二维数组: 2-D多维数组可以被视为数组的数组,也可以被视为由行和列组成的矩阵。
二维阵列
- 三维数组: 3-D多维数组包含三个维度,因此可以将其视为二维数组的数组。
数组运算的类型:
- 遍历:遍历数组的元素。
- 插入:在数组中插入一个新元素。
- 删除:从数组中删除元素。
- 搜索:在数组中搜索元素。
- 排序:保持数组中元素的顺序。
使用数组的优点:
- 数组允许随机访问元素。这使得按位置访问元素变得更快。
- 数组具有更好的缓存局部性,这在性能上有很大的差异。
- 数组使用单个名称表示相同类型的多个数据项。
- 数组存储多个具有相同名称的相似类型的数据。
- 数组数据结构用于实现其他数据结构,如链表、堆栈、队列、树、图等。
数组的缺点:
- 由于数组的大小是固定的,一旦分配了内存,就无法增加或减少,因此无法在需要时存储额外的数据。固定大小的数组称为静态数组。
- 为数组分配少于所需的内存会导致数据丢失。数组本质上是同构的,因此单个数组不能存储不同数据类型的值。
- 数组将数据存储在连续的内存位置,这使得删除和插入非常难以实现。通过实现链表可以克服这个问题,链表允许顺序访问元素。
数组算法
查找给定三个数组中的重复元素
算法讲解:
- 们需要清楚数组是已经排序好的还是没有排序好的,如果没有排序我们需要将三个数组进行升序排。
- 对排完序的数组我们依次比较
- 然后对最新元素的索引+1或者到下一个元素
- 一直比较完
go
func getSameItemSlice(s1, s2, s3 []int) []int {
var x, y, z int = 0, 0, 0
var rest []int
for {
if x < len(s1) && y < len(s2) && z < len(s3) {
if s1[x] == s2[y] && s2[y] == s3[z] {
rest = append(rest, s1[x])
x++
y++
z++
} else if s1[x] < s2[y] {
x++
} else if s2[y] < s3[z] {
y++
} else {
z++
}
continue
}
break
}
return rest
}
// 测试
func Test2(t *testing.T) {
var ar1 = []int{1, 5, 10, 20, 40, 80}
var ar2 = []int{6, 7, 20, 80, 100}
var ar3 = []int{3, 4, 15, 20, 30, 70, 80, 120}
rest := getSameItemSlice(ar1, ar2, ar3)
fmt.Println(rest)
}
复杂度分析: 比较三个数组,我们的循环次数依赖于最小长度的数组,我们只需要循环一次即可,所以我们的时间复杂度为: O(N),N 的长度取决于最短的那个数组。
空间复杂度 :我们需要保存最后的相同的元素的结果,所以我们需要 var rest []int
来保存。 所以空间复杂度为 O(1)