左神算法-提升01-哈希表
左神算法-提升01-哈希表
设计RandomPool结构
【题目】
设计一种结构,在该结构中有如下三个功能:
insert(key):将某个key加入到该结构,做到不重复加入
delete(key):将原本在结构中的某个key移除
getRandom(): 等概率随机返回结构中的任何一个key。
【要求】
Insert、delete和getRandom方法的时间复杂度都是O(1)
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); // 0 ~ size -1
return this.indexKeyMap.get(randomIndex);
}
}
岛问题
【题目】
一个矩阵中只有0和1两种值,每个位置都可以和自己的上、下、左、右 四个位置相连,如
果有一片1连在一起,这个部分叫做一个岛,求一个矩阵中有多少个岛?
【举例】
001010
111010
100100
000000
这个矩阵中有三个岛
【进阶】
如何设计一个并行算法解决这个问题
private static int N;
private static int M;
public static int countIslands(int[][] m) {
if (m == null || m[0] == null) {
return 0;
}
N = m.length;
M = m[0].length;
int islandNum = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (m[i][j] == 1) {
infect(m, i, j);
islandNum++;
}
}
}
return islandNum;
}
public static void infect(int[][] m, int i, int j) {
if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) {
return;
}
m[i][j] = 2;
infect(m, i - 1, j);
infect(m, i + 1, j);
infect(m, i, j - 1);
infect(m, i, j + 1);
}
并查集结构的详解和实现
/**
* 数组实现
*/
public class UnionFind {
private final int MAX_SIZE;
private int[] parent;
private int[] rank;
public UnionFind(int maxSize) {
MAX_SIZE = maxSize;
parent = new int[MAX_SIZE];
rank = new int[MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++) {
parent[i] = i;
rank[i] = 1;
}
}
private int find(int a) {
if (parent[a] != a) {
parent[a] = find(parent[a]);
rank[parent[a]]--;
}
return parent[a];
}
public boolean isSameSet(int a, int b) {
return find(a) == find(b);
}
public void union(int a, int b) {
int aRoot = find(a);
int bRoot = find(b);
if (aRoot == bRoot) {
return;
}
if (rank[aRoot] > rank[bRoot]) {
parent[bRoot] = aRoot;
} else if (rank[bRoot] > rank[aRoot]) {
parent[aRoot] = bRoot;
} else {
parent[bRoot] = aRoot;
rank[aRoot]++;
}
}
}
/**
* map实现
*/
public static class UnionFindSet<T> {
private HashMap<T, T> parentMap;
private HashMap<T, Integer> rankMap;
public UnionFindSet(List<T> list) {
parentMap = new HashMap<>();
rankMap = new HashMap<>();
list.forEach(t -> {
parentMap.put(t, t);
rankMap.put(t, 1);
});
}
public boolean isSameSet(T t1, T t2) {
if (!parentMap.containsKey(t1) || !parentMap.containsKey(t2)) {
return false;
}
return find(t1) == find(t2);
}
private T find(T t) {
if (parentMap.get(t) != t) {
parentMap.put(t, find(parentMap.get(t)));
}
return parentMap.get(t);
}
private T findHead(T t) {
Stack<T> path = new Stack<>();
while (t != parentMap.get(t)) {
path.push(t);
t = parentMap.get(t);
}
while (!path.isEmpty()) {
parentMap.put(path.pop(), t);
}
return t;
}
public void union(T t1, T t2) {
if (!parentMap.containsKey(t1) || !parentMap.containsKey(t2)) {
return;
}
T t1F = findHead(t1);
T t2F = findHead(t2);
if (t1F == t2F) {
return;
}
int compare = rankMap.get(t1F).compareTo(rankMap.get(t2F));
if (compare > 0) {
parentMap.put(t2F, t1F);
rankMap.remove(t2F);
} else {
parentMap.put(t1F, t2F);
rankMap.put(t2F, compare == 0 ? rankMap.get(t1F) + 1 : rankMap.get(t1F));
rankMap.remove(t1F);
}
}
}

浙公网安备 33010602011771号