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

设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。

注意: 允许出现重复元素。

insert(val):向集合中插入元素 val。
remove(val):当 val 存在时,从集合中移除一个 val。
getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
示例:

// 初始化一个空的集合。
RandomizedCollection collection = new RandomizedCollection();

// 向集合中插入 1 。返回 true 表示集合不包含 1 。
collection.insert(1);

// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
collection.insert(1);

// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
collection.insert(2);

// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
collection.getRandom();

// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
collection.remove(1);

// getRandom 应有相同概率返回 1 和 2 。
collection.getRandom();

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/insert-delete-getrandom-o1-duplicates-allowed

解决方法:借用map来处理O(1)时间复杂度,借用List来处理random来处理返回的随机值

问题点:此处理方案有一个不太好的点,remove需要遍历所有的数据,对比官方答案中,把每个val对应的索引放在map的set集合中,通过空间来换时间。 有一个巧妙之后在于,每一次remove都是去掉list尾部的数据(找到对应的数据,再跟尾部的数据互换)

class RandomizedCollection {

    //如果是没有random,那么一个map就够了
    private Map<Integer,Integer> cache;


    //设置值列表,用于计算random
    private List<Integer> valueList;

    /** Initialize your data structure here. */
    public RandomizedCollection() {
        cache = new HashMap<Integer,Integer>();
        valueList = new ArrayList<Integer>();
    }
    
    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    public boolean insert(int val) {
        valueList.add(val);
        if(cache.containsKey(val)){
            cache.put(val,cache.get(val) + 1);
            return false;
        } else {
            cache.put(val,1);
            return true;
        }
    }
    
    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    public boolean remove(int val) {
        if(cache.containsKey(val)){
            if(cache.get(val) > 1){
            cache.put(val,cache.get(val) - 1);
        } else {
             cache.remove(val);
        }
        Iterator<Integer> iterator = valueList.iterator();
        while(iterator.hasNext()){
            if(iterator.next() == val){
                iterator.remove();
                return true;
            }
        }
        return true;
        }
        return false;
    }
    
    
    /** Get a random element from the collection. */
    public int getRandom() {
        Random random = new Random();
        return valueList.get(random.nextInt(valueList.size()));
    }
}

/**
 * Your RandomizedCollection object will be instantiated and called as such:
 * RandomizedCollection obj = new RandomizedCollection();
 * boolean param_1 = obj.insert(val);
 * boolean param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */
一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻
原文地址:https://www.cnblogs.com/fengtingxin/p/13906971.html