目录:
1)哈希函数与哈希表
2)布隆过滤器详解
3)一致性哈希结构
4)并查集结构与应用(岛问题)
题目一:认识哈希函数和哈希表
- 哈希函数的性质:
- 输入域:无穷大
- 输出域S:有限(hashcode十六进制)。十六位,每一位可以从0-9,a-f中选一个(1616 = 2 64)。
- 同样的输入,有同样的输出
- 不同的输入,可能也有同样的输出
- 输入域数据量多了之后,在输出域S中均匀分布,因其离散性
- 要扩容,但扩容是成倍扩的,不是时刻扩。还可以离线扩。所以有了这些技巧,哈希表的增删改查的时间复杂度还是O(1)。
- 经典哈希:产生冲突时,挂成链表结构。因为均匀,所以后面挂的链是均匀上涨的。
- 扩展哈希:挂的不再是链表,而是红黑树结构。
- 哈希函数在大数据领域中的应用:
- 背景:一个很大的文件,有100T。其中存着字符串文本,目的要找出重复的文本,达到去重的效果。
- 解决方法:用哈希来分流。分配1000台机器,给机器标号0-999。把这个大文件中的数据分到1000台机器中去。相同的文本一定会分到同一个机器中去。
- 把每行读出来,利用哈希函数算出hashcode,再把hashcode取模1000,模出来的值即为这一行要放的机器号中。重复的文本会来到同一台机器中。
题目二:设计RandomPool结构
【题目】 设计一种结构,在该结构中有如下三个功能:
- insert(key):将某个key加入到该结构,做到不重复加入。
- delete(key):将原本在结构中的某个key移除。
- getRandom(): 等概率随机返回结构中的任何一个key。
【要求】 Insert、delete和getRandom方法的时间复杂度都是 O(1)。
- 提示:默认哈希函数的增删改查的时间复杂度都为O(1)。
- 准备两张哈希表(为了严格等概率返回任何一个key)。
- 使用哈希表,而不是改造哈希表。
-
只有add和getrandom操作
-
再加上remove操作:产生洞的时候,用最后一行string数据去填这个洞,再把最后一行数据删掉。此时,在整个index中还是连续的。(标index是为了每次getrandom时有数据)
public static class Pool<K> {
//K为泛型
private HashMap<K, Integer> keyIndexMap;
private HashMap<Integer, K> indexKeyMap;
private int size;
public Pool() {
this.keyIndexMap = new HashMap<K, Integer>();
this.indexKeyMap = new HashMap<Integer, K>();
this.size = 0;
}
public void insert(K key) {
if (!this.keyIndexMap.containsKey(key)) {
this.keyIndexMap.put(key, this.size);
this.indexKeyMap.put(this.size++, key);
}
}
public void delete(K key) {
if (this.keyIndexMap.containsKey(key)) {
int deleteIndex = this.keyIndexMap.get(key)