Loading

左神算法-提升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);
            }
        }
    }
posted @ 2023-10-23 01:09  zhangj9  阅读(28)  评论(0)    收藏  举报