380. Insert Delete GetRandom O(1) && 381. 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.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();
public class RandomizedSet { private ArrayList<Integer> nums = new ArrayList<>(); private HashMap<Integer, Integer> locations = new HashMap<>(); private java.util.Random rand = new java.util.Random(); /** * Inserts a value to the set. Returns true if the set did not already contain the specified element. */ public boolean insert(int val) { boolean contain = locations.containsKey(val); if (contain) return false; locations.put(val, 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) { Integer index = locations.get(val); if (index == null) return false; //swap this val to the end of the array before removing. //otherwise, it is not an O(1) operation for deleting the element. if (index < nums.size() - 1) { int lastVal = nums.get(nums.size() - 1); nums.set(index, lastVal); locations.put(lastVal, index); } locations.remove(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())); } } /** * 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(); */
381. 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.
insert(val): Inserts an item val to the collection.remove(val): Removes an item val from the collection if present.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();
The only change from problem 380 is that we use a HashSet to keep different locations for the same value, and update the hashmap when inserting and removing.
public class RandomizedCollection { private ArrayList<Integer> nums = new ArrayList<>(); //use a deque to keep all locaionMap of the same value, and remove them one by one private HashMap<Integer, Set<Integer>> locaionMap = new HashMap<>(); private java.util.Random rand = new java.util.Random(); /** * Inserts a value to the set. Returns true if the set did not already contain the specified element. */ public boolean insert(int val) { Set<Integer> locs = locaionMap.get(val); boolean contains = locs != null; if (!contains) { locs = new HashSet<>(); locaionMap.put(val, locs); } locs.add(nums.size()); nums.add(val); return contains; } /** * Removes a value from the set. Returns true if the set contained the specified element. */ public boolean remove(int val) { Set<Integer> valLocations = locaionMap.get(val); if (valLocations == null) return false; int index = valLocations.iterator().next(); //must remove before the if-statement, e.g have inserted (3,3) //we will swap 3 and 3, and remove the last index(1) from lastValLocations, and then add 0 //but 0 is already there if we don't remove it here. valLocations.remove(index); //You will see the bug if you move this statement after the if block //swap this val to the end of the array before removing. //otherwise, it is not an O(1) operation for deleting the element. if (index < nums.size() - 1) { int lastVal = nums.get(nums.size() - 1); Set<Integer> lastValLocations = locaionMap.get(lastVal); nums.set(index, lastVal); //move lastVal to index position //update the location map for lastVal lastValLocations.remove(nums.size() - 1); lastValLocations.add(index); } if (valLocations.isEmpty()) locaionMap.remove(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())); } } /** * Your RandomizedCollection object will be instantiated and called as such: * RandomizedCollection obj = new RandomizedCollection(); * boolean param_1 = obj.insert(val); * boolean param_2 = obj.remove(val); * int param_3 = obj.getRandom(); */

浙公网安备 33010602011771号