380. Insert Delete GetRandom O(1)

题目

Design a data structure that supports all following operations in average O(1) time.
insert(val): Inserts an item val to the set if not already present.
remove(val): Removes an item val from the set if present.
getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

分析

设计一个数据结构,对于三种基础操作平均时间复杂度为O(1),插入、删除和随机获取某一个元素
随机获取某个元素,可以用一个List存放所有的数据,用java.util.Random函数选取一个Index输出。
插入也可以直接插入到这个List的末尾。
但是删除的时候就不能保证是O(1)的时间复杂度了。因为如果只有一个List可用,查找O(n),删除移动也有O(n)。
为了解决删除的问题,加一个map记录元素和元素在List中的位置,要删除时可以通过这个map将查找时间缩小到O(1),为了防止删除移动和保证插入操作的简单一致性(插到末尾),每次只删除最后一个位置的元素,如果要删的元素不在这个位置,则将最后一个位置的元素与这个元素调换,再进行删除。
这个版本是不允许有重复记录的,下一题会讲怎么处理允许重复记录的情况。

代码

class RandomizedSet {

    private List list;
    private Map map;
    java.util.Random rand = new java.util.Random();
    
    /** Initialize your data structure here. */
    public RandomizedSet() {
        list = new ArrayList();
        map = new HashMap();
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {  //每次插入直接插入到末尾
        if(map.containsKey(val)) return false;
        map.put(val, list.size());
        list.add(val);
        return true;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        //从map中删除
        if(!map.containsKey(val)) return false;
        
        int index = map.get(val);
        map.remove(val);
        
        if(index != list.size() - 1){  //不是最后一个需要跟最后一个调换位置
            int lastValue = list.get(list.size() - 1);
            list.set(index, lastValue);  //改变list位置
            map.put(lastValue, index);   //改变map记录
        }
        
        list.remove(list.size() - 1);
        return true;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        return list.get(rand.nextInt(list.size()));
    }
}

/**
 * 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();
 */

你可能感兴趣的:(380. Insert Delete GetRandom O(1))