380. Insert Delete GetRandom O(1)
Design a data structure that supports all following operations inaverage 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 2 is the only number in the set, getRandom always return 2.
randomSet.getRandom();
Solution 1: HashMap + ArrayList O(1); O(n)
代码包括了381的代码,方便对比。
/**
* HashMap + ArrayList O(1); O(n)
* Use ArrayList to store all values
* Use HashMap to store values and their indexes in ArrayList
* Every insert : index + 1
* Every remove : Put the last value in the removed location and remove the last one
*/
Map<Integer, Integer> map;
// HashMap<Integer, Set<Integer>> map;
List<Integer> nums;
Random rand;
// /** Initialize your data structure here. */
public InsertDeleteGetRandom() {
map = new HashMap<>();
// map = new HashMap<Integer, Set<Integer>>();
nums = new ArrayList<>();
rand = 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;
}
// if (!map.containsKey(val)) {
// map.put(val, new HashSet<Integer>());
// }
map.put(val, nums.size());
// map.get(val).add(nums.size());
nums.add(val);
return true;
}
// /** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
if (!map.containsKey(val)) {
return false;
}
int index = map.get(val);
//no need to add this code: if (index < nums.size() - 1)
//not the last one than swap the last one with this val
int last = nums.get(nums.size() - 1);
map.put(last, index);
nums.set(index, last);
// int index = map.get(val).iterator().next(); //get index of val in ArrayList
// map.get(val).remove(index); //remove index of val in HashSet
// if (index < nums.size() - 1) { //this code is necessary here, otherwise will lead to out of bound
//// int last = nums.get(nums.size() - 1 ); //get the last val
//// nums.set(index , last); //replace val by last val
//// map.get(last).remove(nums.size() - 1); // remove index of last val
//// map.get(last).add(index); //add new index of last val
// }
map.remove(val);
// if (map.get(val).isEmpty()) map.remove(val); //if val's HashSet is empty, remove key of val
nums.remove(nums.size() - 1);
return true;
}
// Get a random element from the set.
public int getRandom() {
return nums.get(rand.nextInt(nums.size()));
}
Follow Up:
1.allow duplicates 相关面试题(L): http://www.1point3acres.com/bbs/thread-156459-1-1.html
Solution 1: HashMap + HashSet + ArrayList O(1); O(n)
The idea is to change the value of hashMap from Integer to HashSet to remember all the locations of a duplicated number.
Map<Integer, Set<Integer>> map;
List<Integer> nums;
Random rand;
///** Initialize your data structure here. */
public InsertDeleteGetRandomII() {
map = new HashMap<>();
nums = new ArrayList<>();
rand = 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.put(val, new HashSet<>());
map.get(val).add(nums.size());
nums.add(val);
return true;
}
map.get(val).add(nums.size());
nums.add(val);
return false;
}
///** 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 index = map.get(val).iterator().next();
map.get(val).remove(index);
if (index < nums.size() - 1) {
int last = nums.get(nums.size() - 1);
nums.set(index, last);
map.get(last).remove(nums.size() - 1);
map.get(last).add(index);
}
if (map.get(val).isEmpty()) {
map.remove(val);
}
nums.remove(nums.size() - 1);
return true;
}
///** Get a random element from the collection. */
public int getRandom() {
return nums.get(rand.nextInt(nums.size()));
}