一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情
集合列表和数组
什么是集合?
- 由一个或者多个 确定 元素构成的整体
- 集合中的元素类型不一定相同
- 集合里的元素没有顺序
什么是列表?
- 按照一定的线性顺序,排列而成的的数据项集合
- 有顺序
- 长度可变
什么是数组?
- 数组是列表的实现方式之一
- 数组拥有元素索引:0,1,2...,而列表没有索引
- 数组中的元素在内存中是连续存储的,且每个元素占用相同的内存大小
注意:列表中的元素在内存中可能彼此相邻,也可能不相邻。比如列表的另一种实现方式--链表(后面介绍)
数组的操作
读取元素
由于数组的内存地址是连续的,我们通过数组下标去读取数组元素的时候,只需要通过索引为 0 处的内存地址加上对应的下标即可
假设有数组 root = ['c','o','d','e','r'],我们想要获取索引为 2 处的元素 d 时,计算机会进行如下计算
- 找到索引
0的内存地址, - 将该地址加上索引值即为目标元素的地址,对应元素
d
因此,通过索引读取元素的时间复杂度是常数级别,为 O(1)
查找元素
假如我们对数组中有哪些元素并不了解,只想知道数组中是否包含某个元素,数组会如何查找元素呢?
还是假设有数组 root = ['c','o','d','e','r'] ,我们想要查找元素 e
与读取元素类似,在查找元素时,只需要从数组开头逐步向后查找就可以,如果数组中的某个元素为目标元素,则停止查找;否则继续搜索直到到达数组的末尾
最坏的情况下,搜索的元素在最后一个时,我们需要查找 n 次,n 为数组的长度,因此查找元素的时间复杂度为 O(N)
插入元素
root = ['c','o','d','e','r']
假如我们想在原来的数组里面再插入一个元素呢?
比如,现在要将 's' 插入数组 root 的第二个位置,我们要怎么做呢
- 将索引
2以及它后面的所有元素都往后挪动一位,腾出索引为2的位置 - 将 's' 插入索引为
2的位置
最坏的情况下,如果要将元素插入第一个位置,我们需要挪动 n 次,n 为数组的长度,在进行插入操作,因此插入元素的时间复杂度为O(N)
删除元素
删除元素和插入元素类似,当我们删除某个元素之后,该数组中会留下一个位置的内存空缺
这时候原先位于被删除元素后面的所有元素,都要往前一位进行填补操作
现假设有一个长度为 n 的数组,在最坏的情况下,我们删除第一个元素,则需要进行如下操作
- 删除第一个元素
- 将剩下的
n - 1个元素向前挪一位
所以最终需要操作的步骤是:1 + (n - 1) = n
即删除数组元素的时间复杂度为O(N)
数组练习题
练习一-数组中心索引
题目
给你一个整数数组 nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
示例
输入:nums = [1, 7, 3, 6, 5, 6] 输出:3
解释
中心下标是 3 左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 , 右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
基础解答
优化版
练习二-搜索插入位置
题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例
输入: nums = [1,3,5,6],target = 5
输出:2
输入: nums = [1,3,5,6],target = 7
输出:4
二分法解答
练习三-合并区间
题目
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].