个人技术分享

目录

集合:

特性:

列表:

数组:

数组操作:

读取

查找

插入

删除

寻找数组的中心索引

搜索插入位置

合并区间

如何区分列表数组?

二维数组


集合:

集合一般被定义为:由一个或多个确定的元素所构成的整体。

特性:

集合里的元素类型不一定相同。

集合里的元素没有顺序。 

这样的集合并不直接存在于编程语言中。然而,实际编程语言中的很多数据结构,就是在集合的基础上添加了一些规则形成的。

列表:

列表的概念是在集合的特征上形成的,它具有顺序,且长度是可变的。你可以把它看作一张购物清单。

列表最常见的表现形式有数组和链表,而我们熟悉的栈和队列则是两种特殊类型的列表。除此之外,向列表中添加、删除元素的具体实现方式会根据编程语言的不同而有所区分。

数组:

数组是列表的实现方式之一。

其次,数组中的元素在内存中是连续存储的,且每个元素占用相同大小的内存。

相反,列表中的元素在内存中可能彼此相邻,也可能不相邻。比如列表的另一种实现方式——链表,它的元素在内存中则不一定是连续的。

比如 C++ 和 Java 中,数组中的元素类型必须保持一致,而 Python 中则可以不同。Python 中的数组叫做 list,具有更多的高级功能。

数组操作:

读取

对于数组,计算机会在内存中为其申请一段 连续 的空间,并且会记下索引为 0 处的内存地址。

先找到数组的索引 0 的内存地址,将内存地址加上索引值,作为目标元素的地址便找到了目标元素。它的时间复杂度是常数级别,为 𝑂(1)。

查找

由于只保存了索引为 0 处的内存地址,因此在查找元素时,只需从数组开头逐步向后查找就可以了。

最坏情况下,搜索的元素为 "R",或者数组中不包含目标元素时,我们需要查找 n 次,n 为数组的长度,因此查找元素的时间复杂度为 O(N),N为数组的长度。

插入

删除

删除元素与插入元素的操作类似,当我们删除掉数组中的某个元素后,数组中会留下 空缺 的位置,而数组中的元素在内存中是连续的,这就使得后面的元素需对该位置进行 填补 操作。

当数组的长度为 n 时,最坏情况下,我们删除第一个元素,共需要的步骤数为 1 + (n - 1) = n 步,其中,1 为删除操作,n - 1 为移动其余元素的步骤数。

即时间复杂度为 𝑂(𝑁)O(N),𝑁N 为数组的长度。

寻找数组的中心索引


给你一个整数数组 nums ,请计算数组的中心下标 。

中心下标(pivot index)是指一个数组中的某个下标,该下标左侧的所有元素之和等于右侧的所有元素之和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置

请必须使用时间复杂度为 O(log n) 的算法。

合并区间


以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

如何区分列表数组?

索引

列表中没有索引。数组索引是从 0 算起的。我们可以根据数组中的索引,快速访问数组中的元素。

二维数组

类似一维数组,对于一个二维数组 A = [[1, 2, 3, 4],[2, 4, 5, 6],[1, 4, 6, 8]],计算机同样会在内存中申请一段 连续 的空间,并记录第一行数组的索引位置,即 A[0][0] 的内存地址,它的索引与内存地址的关系如下图所示。

注意:

旋转矩阵

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?

要将 N × N 矩阵表示的图像旋转 90 度且不占用额外内存,可以通过分层旋转的方式原地进行操作。

零矩阵

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。