力扣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;}}