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

题目链接

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

题目描述

O(1) 时间插入、删除和获取随机元素_第1张图片
O(1) 时间插入、删除和获取随机元素_第2张图片

注意点

  • 在调用 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中的下标idx
        int idx = map.get(val);
        int tail = list.size() - 1;
        // list->idx和tail交换,交换后删除tail
        list.set(idx, list.get(tail));
        // map->更新tail处元素对应的value,删除val
        map.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存储元素
  • 删除元素的几个步骤

你可能感兴趣的:(算法,算法,数据结构,leetcode,java)