Insert Delete GetRandom O(1) & Duplicates allowed

380. Insert Delete GetRandom O(1)

Design a data structure that supports all following operations in average O(1) time.dom

  1. insert(val): Inserts an item val to the set if not already present.code

  2. remove(val): Removes an item val from the set if present.ci

  3. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.element

思路

HashSet能夠實現O(1)時間複雜度的insert和remove,可是要求getRandom也是O(1),只用HashSet是不能夠的。在List裏面隨機找一個數的時間是O(1),因此能夠用list來記錄加進去的value,這樣insert和getRandom都是O(1)了。remove的操做比較有意思,在一個list裏面找到相應的值以後和最後一個位置上的值調換,這個remove就是常數時間了。可是在list裏面查找的時間複雜度依然是O(N),能夠想到用hashmap來記錄對應的index,這樣查找的時間也是常數。rem

複雜度

Time: O(1), Space: O(N)get

代碼

Map<Integer, Integer> map;
    List<Integer> list;
    Random random;
    public RandomizedSet() {
        // hashmap to realize insert, remove in O(1), the value is the index in list
        map = new HashMap();
        // list to realize get random in O(1);
        list = new ArrayList();
        random = new Random();
    }
    
    /** 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) {
        // change the val with the last one, then delete last one
        if(!map.containsKey(val)) return false;
        int delete_index = map.get(val);
        int last = list.get(list.size() - 1);
        // change the last element to the delete place
        list.set(delete_index, last);
        // update the index in map
        map.replace(last, delete_index);
        // remove in the list
        list.remove((int) list.size() - 1);
        // remove in the map
        map.remove(val);
        return true;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        if(list.size() == 0) return -1;
        return list.get(random.nextInt(list.size()));
    }

381. Insert Delete GetRandom O(1) - Duplicates allowed

思路

容許duplication以後麻煩了許多。如今hashmap裏面要存全部的index。在remove的時候複雜度要保持O(1),每次仍是要取最後一個值和刪除的值交換,因此須要map裏面找到最後一個值,以後刪除最大的index的時間複雜度是O(1),同時把index更新成當前刪除的值的index以後,全部的index還要保持順序。hash

heap

用heap能夠保持順序,可是poll的時間複雜度是O(logN)。it

代碼

Map<Integer, PriorityQueue<Integer>> map;
    List<Integer> list;
    Random random;
    public RandomizedCollection() {
        map = new HashMap();
        list = new ArrayList();
        random = new Random();
    }
    
    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    public boolean insert(int val) {
        if(map.containsKey(val)) {
            map.get(val).add(list.size());
            list.add(val);
            return false;
        }
        else {
            map.put(val, new PriorityQueue<>((a, b) -> b - a));
            map.get(val).add(list.size());
            list.add(val);
            return true;
        }
    }
    
    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    public boolean remove(int val) {
        if(!map.containsKey(val)) return false;
        int delete_index = map.get(val).peek();
        int last = list.get(list.size() - 1);
        // update
        list.set(delete_index, last);
        map.get(last).poll();
        map.get(last).add(delete_index);
        // delete
        list.remove(list.size() - 1);
        map.get(val).poll();
        if(map.get(val).size() == 0) map.remove(val);
        return true;
    }
    
    /** Get a random element from the collection. */
    public int getRandom() {
        return list.get(random.nextInt(list.size()));
    }

LinkedHashSet

相關文章
相關標籤/搜索