LeetCode-Insert Delete GetRandom O(1) - Duplicates allowed

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

Note: Duplicate elements are allowed.

 

  1. insert(val): Inserts an item val to the collection.
  2. remove(val): Removes an item val from the collection if present.
  3. getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.

Example:

// Init an empty collection.
RandomizedCollection collection = new RandomizedCollection();

// Inserts 1 to the collection. Returns true as the collection did not contain 1.
collection.insert(1);

// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
collection.insert(1);

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
collection.insert(2);

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
collection.getRandom();

// Removes 1 from the collection, returns true. Collection now contains [1,2].
collection.remove(1);

// getRandom should return 1 and 2 both equally likely.
collection.getRandom();

Analysis:
Because duplicates are allowed, we use a HashSet to store every index of a number.
 1 import java.util.Random;
 2 
 3 public class RandomizedCollection {
 4         HashMap<Integer, HashSet<Integer>> numMap;
 5         List<Integer> numList;
 6 
 7         /** Initialize your data structure here. */
 8         public RandomizedCollection() {
 9             numMap = new HashMap<Integer, HashSet<Integer>>();
10             numList = new ArrayList<Integer>();
11         }
12 
13         /**
14          * Inserts a value to the collection. Returns true if the collection did
15          * not already contain the specified element.
16          */
17         public boolean insert(int val) {
18             boolean hasVal = false;
19             if (numMap.containsKey(val)) {
20                 hasVal = true;
21                 numMap.get(val).add(numList.size());
22                 numList.add(val);
23             } else {
24                 HashSet<Integer> set = new HashSet<Integer>();
25                 set.add(numList.size());
26                 numMap.put(val, set);
27                 numList.add(val);
28             }
29             return !hasVal;
30         }
31 
32         /**
33          * Removes a value from the collection. Returns true if the collection
34          * contained the specified element.
35          */
36         public boolean remove(int val) {
37             if (!numMap.containsKey(val))
38                 return false;
39 
40             // Get an index of @val from index set and remove this index from
41             // the set.
42             HashSet<Integer> indSet = numMap.get(val);
43             int ind = indSet.iterator().next();
44             indSet.remove(ind);
45 
46             // Delete the entry, if the index list becomes empty.
47             if (indSet.isEmpty()) {
48                 numMap.remove(val);
49             }
50             
51             
52             // Remove the indexed number from @numList by swapping it to the tail.
53             // Modify the index of the tail number.
54             // NOTE: it is important to check whether @ind is the tail of @numList!
55             if (ind!=numList.size()-1){
56                 int tailNum = numList.get(numList.size() - 1);
57                 numMap.get(tailNum).remove(numList.size() - 1);
58                 numMap.get(tailNum).add(ind);
59                 numList.set(ind, tailNum);
60             }
61             numList.remove(numList.size() - 1);
62 
63             return true;
64         }
65 
66         /** Get a random element from the collection. */
67         public int getRandom() {
68             Random engine = new Random();
69             int ind = engine.nextInt(numList.size());
70             return numList.get(ind);
71         }
72     }

 



posted @ 2016-08-09 13:54  LiBlog  阅读(259)  评论(0编辑  收藏  举报