算法基础(一)- 集合列表和数组

244 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

集合列表和数组

什么是集合?

  1. 由一个或者多个 确定 元素构成的整体
  2. 集合中的元素类型不一定相同
  3. 集合里的元素没有顺序

什么是列表?

  1. 按照一定的线性顺序,排列而成的的数据项集合
  2. 有顺序
  3. 长度可变

什么是数组?

  1. 数组是列表的实现方式之一
  2. 数组拥有元素索引:0,1,2...,而列表没有索引
  3. 数组中的元素在内存中是连续存储的,且每个元素占用相同的内存大小

注意:列表中的元素在内存中可能彼此相邻,也可能不相邻。比如列表的另一种实现方式--链表(后面介绍)

数组的操作

读取元素

由于数组的内存地址是连续的,我们通过数组下标去读取数组元素的时候,只需要通过索引为 0 处的内存地址加上对应的下标即可

假设有数组 root = ['c','o','d','e','r'],我们想要获取索引为 2 处的元素 d 时,计算机会进行如下计算

  1. 找到索引 0 的内存地址,
  2. 将该地址加上索引值即为目标元素的地址,对应元素 d

因此,通过索引读取元素的时间复杂度是常数级别,为 O(1)

查找元素

假如我们对数组中有哪些元素并不了解,只想知道数组中是否包含某个元素,数组会如何查找元素呢?

还是假设有数组 root = ['c','o','d','e','r'] ,我们想要查找元素 e

与读取元素类似,在查找元素时,只需要从数组开头逐步向后查找就可以,如果数组中的某个元素为目标元素,则停止查找;否则继续搜索直到到达数组的末尾

最坏的情况下,搜索的元素在最后一个时,我们需要查找 n 次,n 为数组的长度,因此查找元素的时间复杂度为 O(N)

插入元素

root = ['c','o','d','e','r']

假如我们想在原来的数组里面再插入一个元素呢?

比如,现在要将 's' 插入数组 root 的第二个位置,我们要怎么做呢

  1. 将索引 2 以及它后面的所有元素都往后挪动一位,腾出索引为 2 的位置
  2. 将 's' 插入索引为 2 的位置

最坏的情况下,如果要将元素插入第一个位置,我们需要挪动 n 次,n 为数组的长度,在进行插入操作,因此插入元素的时间复杂度为O(N)

删除元素

删除元素和插入元素类似,当我们删除某个元素之后,该数组中会留下一个位置的内存空缺

这时候原先位于被删除元素后面的所有元素,都要往前一位进行填补操作

现假设有一个长度为 n 的数组,在最坏的情况下,我们删除第一个元素,则需要进行如下操作

  1. 删除第一个元素
  2. 将剩下的 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].