大厂算法面试之 leetcode 精讲 16.set&map
大厂算法面试之 leetcode 精讲 16.set&map
视频讲解(高效学习):点击学习
目录:
集合与字典 :
集合常见的形式是 Set,字典常见的形式是 Map
Set 和 Map 主要的应用场景在于 数据重组 和 数据储存。
集合 与 字典 的区别:
共同点:集合、字典 可以储存不重复的值
不同点:集合类似于数组,元素的只有 key 没有 value,value 就是 key。字典是以 [key, value] 的形式储存,键的范围不限于字符串,各种类型的值(包括对象)都可以当作键
时间复杂度:
set 或 map 可以用哈希表或平衡二叉搜索树实现
哈希表实现的 map 或者 set 查找的时间复杂度是O(1)
,哈希表优点是查找非常快,哈希表的缺点是失去了数据的顺序性,平衡二叉搜索树实现的 map 或 set 查找时间复杂度是O(logn)
,它保证了数据顺序性
哈希函数
哈希函数是一个接受输入值的函数,由此输入计算出一个确定输出。
均匀分布:哈希函数计算出来的地址均匀分布
哈希碰撞:哈希函数计算出来的结果冲突
开放定址法
链地址法
1. 两数之和 (easy)
方法 1.暴力枚举
思路:两层 for 循环,第一层
for i:0->n
-1, 枚举 nums 中的每一个数 x,第二层for j:i+1->n-1
,寻找是否存在两个数字的和是 target。复杂度分析:时间复杂度:
O(n^2)
, n 为数组的长度。空间复杂度O(1)
。
方法 2.哈希表:
思路:方法一第一层循环是必须的,关键是优化第二次循环,也就是寻找
targrt-x
的过程,这里关键采用空间换时间,也就是采用哈希表进行优化,让查找的过程变为O(1)
。首先还是遍历 nums 数组,然后在哈希表中寻找target-x
,如果不存在就把当前元素 x 和下标存入哈希表,如果存在就返回target-x
和当前元素的下标复杂度分析:时间复杂度
O(n)
, n 为数组的长度,空间复杂度O(n)
,n 为数组的长度,主要是哈希表的空间开销
js:
java:
454. 四数相加 II( medium)
方法 1:哈希表
思路:在 A 和 B 中取出两个数的组合,将这两个数的和作为键,出现次数作为值加入哈希表中,循环 C、D,判断 C 和 D 中是否存在两个数的和 加 AB 中的俩元素的和正好是 0,统计组合数
复杂度:时间复杂度
O(n^2)
,两个嵌套循环。空间复杂度O(n^2)
,哈希表的空间,最差的情况下是n^2
js:
java:
242. 有效的字母异位词 (easy)
方法 1.排序
思路:两个字符串转成数组,排序后转回字符串进行比较。
复杂度分析:时间复杂度
O(nlogn)
,排序采用快排,时间复杂度是 nlogn,比较两字符串是否相等时间复杂度为 n,O(n)+O(nlogn)=O(nlogn)
。空间复杂度为O(logn)
,排序需要O(logn)
的空间,java 和 js 字符串是不可变的,需要额外的O(n)
空间来拷贝字符串,我们忽略这个复杂度,这依赖不同语言实现的细节。
方法 2.哈希表:
思路:采用空间换时间的策略,准备一个数组,循环字符串 s,每个元素出现一次加 1,然后循环 t 元素,每次出现的字符减 1,如果 t 中出现一些不在 s 中的字符 则返回 false,所有循环结束 说明两个字符串中每个字符的数量相同
复杂度分析: 时间复杂度
O(n)
,n 是字符串的长度,空间复杂度O(s)
,s 为字符集大小
js:
java:
447. 回旋镖的数量 (medium)
思路:循环数组,找出与当前元素距离相同的点,记录频次加入 map 中,最后循环 map,从相同距离的数量中选取两个组合出来,加入结果中。从 m 个元素中选取两个的排列组合数 是
m*(m-1)
复杂度:时间复杂度
O(n^2)
,数组遍历两层,空间复杂度O(n)
,哈希表的空间
js:
java:
187. 重复的DNA序列 (medium)
思路:用 map 存储子串出现的次数,循环 dna 序列,每次截取长度为 10 的子串,加入 map 中 并更新出现的次数,次数超过 2,加入 ans
复杂度:时间复杂度
O(n)
,n 是字符串的长度。空间复杂度O(n)
js:
java:
49. 字母异位词分组 (medium)
方法 1.排序
思路:遍历字符串数组,对每个字符串中的字符排序,加入 map 对应的 key 的数组中。
复杂度:时间复杂度
O(n*klogk)
,n 是字符串的个数,k 是最长的字符串的长度,排序复杂度O(klogk)
,n 次排序,哈希表更新O(1)
。空间复杂度O(nk)
,排序空间复杂度O(nlogk)
,map 空间复杂度O(nk)
,取较大的O(nk)
js:
java:
方法 2.计数
思路:题意是字符串的字符都是小写,可以对每个字符串统计其中字符的频次,将每个字符频次相同的字符串放在一组
复杂度:时间复杂度
O(n*k)
,n 是字符串个数,k 是最长字符串长度,循环字符串数组复杂度O(n)
,对每个字符串统计频次复杂度O(k)
。空间复杂度O(n*k)
,map 中存放了 n 个大小最长为 k 的字符串。
js:
java:
评论