题目链接
O(1) 时间插入、删除和获取随机元素
题目描述
注意点
- 在调用 getRandom 方法时,数据结构中 至少存在一个 元素
- 满足每个函数的 平均 时间复杂度为 O(1)
解答思路
- 因为要满足满足每个函数的平均时间复杂度为 O(1),只使用List新增和删除的时间复杂度为O(n),只使用Map获取随机元素的时间复杂度为O(n)。所以考虑使用List+Map,其中List存储元素值,Map中key存储元素值,value存储元素在List中的下标
- 在新增元素时,直接将元素添加到List末尾,往Map中存储元素相应信息即可
- 在删除元素时,有以下几个步骤:
- 通过Map获取元素在List中的下标idx
- 将List中tail的元素与idx的元素进行交换
- 将Map中tail元素的value修改为idx
- 删除List和Map中的元素
- 获取随机元素使用random获取List范围中的元素即可
代码
class RandomizedSet {// key->值,value->值在list中的下标Map<Integer, Integer> map;List<Integer> list;Random random;public RandomizedSet() {map = new HashMap<>();list = new ArrayList<>();random = new Random();}public boolean insert(int val) {if (map.get(val) != null) {return false;}list.add(val);map.put(val, list.size() - 1);return true;}public boolean remove(int val) {if (map.get(val) == null) {return false;}// 获得val在list中的下标idxint idx = map.get(val);int tail = list.size() - 1;// list->idx和tail交换,交换后删除taillist.set(idx, list.get(tail));// map->更新tail处元素对应的value,删除valmap.put(list.get(tail), idx);list.remove(tail);map.remove(val);return true;}public int getRandom() {int randomIdx = random.nextInt(list.size());return list.get(randomIdx);}
}/*** Your RandomizedSet object will be instantiated and called as such:* RandomizedSet obj = new RandomizedSet();* boolean param_1 = obj.insert(val);* boolean param_2 = obj.remove(val);* int param_3 = obj.getRandom();*/
关键点
- 使用List+Map存储元素
- 删除元素的几个步骤