Loading

左神算法-提升01-哈希表

左神算法-提升01-哈希表

设计RandomPool结构

【题目】

设计一种结构,在该结构中有如下三个功能:

insert(key):将某个key加入到该结构,做到不重复加入

delete(key):将原本在结构中的某个key移除

getRandom(): 等概率随机返回结构中的任何一个key。

【要求】

Insert、delete和getRandom方法的时间复杂度都是O(1)

public static class Pool {
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 {
private HashMap<T, T> parentMap;
private HashMap<T, Integer> rankMap;

public UnionFindSet(List 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 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);
}
}
}

posted @ 2023-10-23 01:09  zhangj9  阅读(49)  评论(0)    收藏  举报