1 数组
1.1 集合、列表、数组的联系与区别
集合:由一个或多个确定的元素所构成的整体。类型不一定相同、确定、无序、互异。
列表(又称线性列表):按照一定的线性顺序,排列而成的数据项的集合。类型不一定相同、有序、不一定互异。包括数组、栈、队列、链表等
数组(Array):是一种元素在内存中连续存储的线性列表数据结构。类型相同(静态语言)或类型可不同(动态语言)、有序、不一定互异。
1.2 数组基本操作
读取元素:通过数组的 索引(下标)访问数组中的元素。随机访问——时间复杂度O(1)。
为什么数组下标从0开始?
因为,下标从0开始的计算机寻址公式:
相比下标从1开始,a[1]表示数组的首地址的寻址公式:
访问数组元素少一次减法运算,这对于CPU来说,就是少了一次减法指令。
查找元素:从索引 0 处开始,逐步向后查询。时间复杂度 O(n);
插入元素:
- 尾部插入,通过数组的长度计算出即将插入元素的内存地址,然后将该元素插入到尾部。时间复杂度O(1);
- 非尾部插入,将尾部到索引下标之间的元素依次后移,将元素插入索引对应的空出空间。时间复杂度O(n)。
- JavaScript超出数组长度范围插入,对超出部分会自动设置为undefined。
删除元素:
- 尾部删除,直接删除。时间复杂度O(1) ;
- 非尾部删除,删除指定索引元素,后续元素依次向前填补,时间复杂度为 O(n);
更改元素:通过数组的索引(下标)赋值更改。时间复杂度O(1);
二维数组的本质上仍然是一个一维数组,内部的一维数组仍然从索引 0 开始。m * n的二维数组寻址公式为:
,
其中第k个一维数组的首元素的地址为:
。
1.3 数组的优劣
高效O(1)的随机访问,低效O(n)的查找、插入和删除元素。因此,数组所适合的是读、改操作多,查、删操作少的场景。
1.4 剑指 offer 数组算法题(typescript 版)
二维数组的查找
旋转数组的最小数字
调整数组顺序使奇数位于偶数前面
数组中出现次数超过一半的数字
连续子数组的最大和
把数组排成最小的数
数组的逆序对
数字在排序数组的出现次数
数组中只出现一次的两个数字(其余出现均两次)
数组中重复的数字
构建乘积数组
顺时针打印矩阵
最小的K个数
和为S的两个数字
扑克牌中的顺子
滑动窗口的最大值
2 字符串
字符串是由零个或多个字符组成的有限序列。用成对双引号或成对单引号的形式存在
2.1 字符串基本操作
与数组类似,通过下标访问其中字符。
字符串可能是可变(C++),也可能是不可变的(python,JavaScript),不可变意味着初始化后不能修改其中字符。对于不可变的字符串,连接操作意味着首先为新字符串分配足够的空间,复制旧字符串中的内容并附加到新字符串,时间复杂度为O(N)。
2.2 剑指 offer 字符串算法题(typescript 版)
字符串的排列
字符串的空格替换
第一个只出现一次的字符
左旋字符串
翻转单词顺序列
把字符串转换成数字
正则表达匹配
表示数值的字符串
字符串中重复次数最多的字符
Hex颜色值转rgb
无重复字符的最长子串
千分位分隔数字