力扣labuladong一刷day26天常数时间访问删除操作数组

力扣labuladong一刷day26天常数时间访问删除操作数组

文章目录

      • 力扣labuladong一刷day26天常数时间访问删除操作数组
      • 一、380. O(1) 时间插入、删除和获取随机元素
      • 二、710. 黑名单中的随机数

一、380. O(1) 时间插入、删除和获取随机元素

题目链接:https://leetcode.cn/problems/insert-delete-getrandom-o1/
思路:map可以做到O(1)的插入、删除、获取,但是做不到O(1)的随机获取。list通过索引可以做到O(1)的随机获取。故结合list和map,list存元素,map存元素和索引,添加就尾部添加,删除把该元素与尾部元素交换再删除,这样其他的索引都不影响,也是O(1)的删除,随机获取就是Random然后通过索引获取list。

class RandomizedSet {
    private Map<Integer, Integer> map;
    private List<Integer> list;
    public RandomizedSet() {
        map = new HashMap<>();
        list = new ArrayList<>();
    }

    public boolean insert(int val) {
        if (map.containsKey(val)) return false;
        map.put(val, list.size());
        list.add(val);
        return true;
    }

    public boolean remove(int val) {
        if (!map.containsKey(val)) return false;
        Integer index = map.get(val);
        Integer value = list.get(list.size() - 1);

        Collections.swap(list, index, list.size()-1);
        map.put(value, index);

        list.remove(list.size()-1);
        map.remove(val);
        return true;
    }

    public int getRandom() {
        Random random = new Random();
        int i = random.nextInt(list.size());
        return list.get(i);
    }
}

二、710. 黑名单中的随机数

题目链接:https://leetcode.cn/problems/random-pick-with-blacklist/
思路:这题和上一题类型,区间内有一部分数不可用,需要做一个映射,我们只需要把黑名单里的数对应成N尾部不在黑名单里的数,然后只在n-黑名单数量的范围内随机,如果随机出来的数是黑名单里的数直接返回对应的末尾值即可,就是做了一个映射替换,不过其中有一点要注意,提前给黑名单排个序。

class Solution {
    Set<Integer> set;
    Map<Integer, Integer> map;
    Random random = new Random();
    int len;
    public Solution(int n, int[] blacklist) {
        len = n - blacklist.length;
        set = new HashSet<>(blacklist.length);
        Arrays.sort(blacklist);
        for (int i : blacklist) {
            set.add(i);
        }
        map = new HashMap<>();
        int right = n-1;
        for (int i : blacklist) {
            while (set.contains(right)) right--;
            map.put(i, right--);
        }
    }

    public int pick() {
        int i = random.nextInt(len);
        if (map.containsKey(i)) return map.get(i);
        else return i;
    }

}

你可能感兴趣的:(力扣算法题,leetcode,算法,职场和发展)