Sunday, August 7, 2016

LeetCode 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.

Example:

// Init an empty set.
RandomizedSet randomSet = new RandomizedSet();
// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1);
// Returns false as 2 does not exist in the set.
randomSet.remove(2);
// Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2);
// getRandom should return either 1 or 2 randomly.
randomSet.getRandom();
// Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1);
// 2 was already in the set, so return false.
randomSet.insert(2);
// Since 1 is the only number in the set, getRandom always return 1.
randomSet.getRandom();

The follow-up: allowing duplications.
For example, after insert(1), insert(1), insert(2), getRandom() should have 2/3 chance return 1 and 1/3 chance return 2.
Then, remove(1), 1 and 2 should have an equal chance of being selected by getRandom().

The idea is to add a set to the hashMap to remember all the locations of a duplicated number.

indexMap<Integer, Integer> stores key-index pair, where index is the index in the List. This hash table is to support delete operation in O(1) time.

List is for getRandom() method.

There is another tricky place in Delete operation. Instead of compare the trade off between ArrayList and LinkedList, maintain a variable N to store the number of keys in this data structure, whenever a delete operation is executed, just swap the keys with the last one and decrement N by one. In this way, delete operation is guaranteed in Constant time.