# 380、O(1) 时间插入、删除和获取随机元素
哈希
哈希算法
通过一个散列函数将任意长度的输入转化为固定长度的输出
在哈希表中用来计算某个键值存储的地址
因此哈希表的查询时间复杂度即为哈希算法的时间复杂度 O(1)
牺牲空间复杂度从而换取时间复杂度
负载因子
存储数据的个数 / 使用空间的数量(小于1)
太小容易导致哈希冲突,太大浪费空间
哈希表
本质上与字典类似,都是存储的键值对
但是哈希表可以利用哈希算法提高查询速度
即哈希表中元素的存储位置与其本身存在函数关系
解决冲突
线性探查;双散列函数:跳跃探查
构造散列函数
直接寻址:线性函数关系;数学分析:取部分;
平方取中;折叠;随机数;除留余数
randint(a,b)
取 [a,b] 之间的整数
闭区间,两端都可以取得到
# 238、除自身以外数组的乘积
思路
前后缀乘积列表
前缀乘积存储在最后的答案中并更新
后缀乘积存储在一个常数中并更新
前后各循环一次
# 134、加油站
思路
双重循环遍历数组
每次寻找下一个不能到达的加油站
下一个循环从该加油站开始
因为中间的加油站出发也不可能到达该加油站的下一个
单次循环
找到从开始累计的最小剩余油量(负数)所在的位置
需要判断总剩余油量若为负返回-1
否则该位置的下一个位置即为所求
注意
该题保证只有唯一解
因此可以采用贪心思想
# 13、罗马数字转整型
思路
哈希表字典存储单一罗马字符对应的键值
遍历整个字符串后累加求解
如何处理 IV IX 等情况
字典中将两个字母的情况也存下来
左比右小则先减 I 后加 V X
将 IV 存为3 IX 存为 8,保证累加结果不变
# 12、整型转罗马数字
思路
贪心+哈希表
每次找最大匹配的键值
暴力匹配
把诸如 II III 通通存进哈希表
# 58、最后一个单词的长度
思路
反向遍历,遇见空格停止,统计单词长度
注意
可能文末还有额外空格
# 14、最长公共前缀
思路
横向遍历
遍历所有单词,同时维护更新最长公共前缀
纵向遍历
依次比较每个单词相同位置的字符
分治
所有字符串的最长公共前缀一定是子字符串集的公共前缀
二分查找
最长公共前缀不会超过最短字符串长度
依次迭代递归查找二分长度的子字符串是否为公共子字符串
后两个方法不比前两个更优
# 151、反转字符串中的单词
思路
倒序遍历
从后往前遍历字符串,每找到一个单词,就加入最终字符串
调库
split reverse join,划分单词、翻转单词、重新组合
双端队列
头尾均可,类似于双向栈
# 6、Z字形变换
思路
二维矩阵
压缩矩阵空间,减少为空的元素
下标取模
直接获取对应行列元素下标关系
变向模拟
多个子字符串分别存储各行,最后合并
# 28、找出字符串中第一个匹配项的下标
思路
暴力匹配:两个指针分别遍历待匹配字符串和匹配字符串
KMP算法:每次匹配失败时,寻找匹配串相同前后缀的下一位
Sunday算法:未找到匹配时通过偏移表决定下一匹配位置