实现一个添加、删除、随机获得元素都是O(1)的数据结构

1. 分析

我们都知道在JavaHashMap中插入和删除的时间复杂度为O(1),故而我们可以考虑使用HashMap来作为底层的数据存储,但是因为HashMap中没有索引,所以在随机获取一个元素的时候做不到时间复杂度为O(1),所以需要引入额外的数据结构ArrayList

在随机获取一个元素的时候,我们就在ArrayList中随机生成一个下标,然后返回其值即可。
在添加和删除的时候,使用HashMap来完成。

这里需要解决的主要问题就是如何将两者进行关联起来。比如:在删除元素的时候,应该不仅是在HashMap中删除,而且需要对应的删除ArrayList中的值,而如果没有特殊的关联,那么在ArrayList中进行删除元素的查找就是O(n)的时间复杂度了,显然不满足需求。

2. 解决

HashMap中存储<key, value>,那么key可以存储为当前的值,而value为当前值在ArrayList的下标。
ArrayList中存储的元素是具体的值。

在这里插入图片描述

通过上面的映射,可以做到添加和删除的时候及时更新ArrayList的值,然后可以做到随机获取一个元素。

在添加和删除的时候,需要更新这两部分即可。操作规则为:

  • 插入一个数时,直接放到ArrayList最后;
  • 删除一个数时,让ArrayList最后一个数字去替换当前待删除元素;
class RandomizedSet {
    
    

    private HashMap<Integer, Integer> map;
    private ArrayList<Integer> list;
    private Random random;

    public RandomizedSet() {
    
    
        map = new HashMap<>();
        list = new ArrayList<>();
        random = new Random();
    }

    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;
        int lastEle = list.get(list.size() - 1);
        int idx = map.get(val);
        list.set(idx, lastEle);
        map.put(lastEle, idx);
        list.remove(list.size() - 1);
        map.remove(val);
        return true;
    }

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

结果:
在这里插入图片描述


题目地址

Guess you like

Origin blog.csdn.net/qq_26460841/article/details/120360876