0%

哈希表&布隆过滤器&并查集

哈希函数,哈希表,RandomPool结构,布隆过滤器,一致性哈希,并查集,岛问题。

认识哈希函数和哈希表

哈希函数

image-20210305140746821

哈希表

image-20210305142622786

设计RandomPool结构

image-20210305142719793

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.util.HashMap;

public class Code_02_RandomPool {

public static class Pool<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);
int lastIndex = --this.size;
K lastkey = this.indexKeyMap.get(lastIndex);
this.keyIndexMap.put(lastkey, deleteIndex);
this.indexKeyMap.put(deleteIndex, lastkey);
this.keyIndexMap.remove(key);
this.indexKeyMap.remove(lastIndex);
}
}

public K getRandom() {
if (this.size == 0) {
return null;
}
int randomIndex = (int) (Math.random() * this.size);
return this.indexKeyMap.get(randomIndex);
}

public static void main(String[] args) {
Pool<String> pool = new Pool<String>();
pool.insert("wu");
pool.insert("xiang");
pool.insert("fivelike");
System.out.println(pool.getRandom());
System.out.println(pool.getRandom());
System.out.println(pool.getRandom());
}
}
}

布隆过滤器

image-20210305155321584

image-20210305155354502

一致性哈希

image-20210305161155391

image-20210305161230491

image-20210305161256377

image-20210305161319472

并查集

image-20210305170743936

image-20210305170807883

image-20210305170834982

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.util.HashMap;
import java.util.List;

public class Code_03_UnionFind {
public static class Node {
// whatever you like
}

public static class UnionFindSet {
public HashMap<Node, Node> fatherMap;
public HashMap<Node, Integer> sizeMap;

public UnionFindSet() {
fatherMap = new HashMap<Node, Node>();
sizeMap = new HashMap<Node, Integer>();
}

public void makeSets(List<Node> nodes) {
fatherMap.clear();
sizeMap.clear();
for (Node node : nodes) {
fatherMap.put(node, node);
sizeMap.put(node, 1);
}
}

private Node findHead(Node node) {
Node father = fatherMap.get(node);
if (father != node) {
father = findHead(father);
}
fatherMap.put(node, father);
return father;
//非递归版本
// Stack<Node> stack = new Stack<Node>();
// Node cur = node;
// Node parent = fatherMap.get(node);
// while (cur != parent){
// stack.push(cur);
// cur = parent;
// parent = fatherMap.get(cur);
// }
// while (stack.isEmpty()){
// fatherMap.put(stack.pop(),parent);
// }
// return parent;
}

public boolean isSameSet(Node a, Node b) {
return findHead(a) == findHead(b);
}

public void union(Node a, Node b) {
// if (a == null || b = null) {
// return;
// }
Node aHead = findHead(a);
Node bHead = findHead(b);
if (aHead != bHead) {
int aSetSize = sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
if (aSetSize <= bSetSize) {
fatherMap.put(aHead, bHead);
sizeMap.put(bHead, aSetSize + bSetSize);
} else {
fatherMap.put(bHead, aHead);
sizeMap.put(aHead, aSetSize + bSetSize);
}
}
}

}
}

岛问题

image-20210305171009075

单任务思路
  • 遇到岛就深度遍历把遍历过的都给标记起来。之后遇到标记过的,直接跳过,直到遇到未标记的岛,就给岛的数量加一;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Code_04_Islands {
public static int countIslands(int[][] m) {
if (m == null || m[0] == null) {
return 0;
}
int N = m.length;
int M = m[0].length;
int res = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (m[i][j] == 1) {
res++;
infect(m, i, j, N, M);
}
}
}
return res;
}

public static void infect(int[][] m, int i, int j, int N, int M) {
if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) {
return;
}
m[i][j] = 2;
infect(m, i + 1, j, N, M);
infect(m, i - 1, j, N, M);
infect(m, i, j + 1, N, M);
infect(m, i, j - 1, N, M);
}
}
多任务思路(并行计算)

image-20210305171631451