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();
本题其实不是很难,只是有一个数据结构需要注意一下,就是linkedhashset,它是链表和hashset的结合,本身带有顺序性,代码如下:
1 public class RandomizedCollection { 2 HashMap<Integer,Set<Integer>> map; 3 List<Integer> nums; 4 java.util.Random rand = new java.util.Random(); 5 /** Initialize your data structure here. */ 6 public RandomizedCollection() { 7 map = new HashMap<>(); 8 nums = new ArrayList<Integer>(); 9 } 10 11 /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ 12 public boolean insert(int val) { 13 boolean contain = map.containsKey(val); 14 if(!contain){ 15 Set<Integer> set = new LinkedHashSet<Integer>(); 16 map.put(val,set); 17 } 18 map.get(val).add(nums.size()); 19 nums.add(val); 20 return !contain; 21 } 22 23 /** Removes a value from the collection. Returns true if the collection contained the specified element. */ 24 public boolean remove(int val) { 25 boolean contain = map.containsKey(val); 26 if(!contain) return false; 27 int loc = map.get(val).iterator().next(); 28 map.get(val).remove(loc); 29 if(loc<nums.size()-1){ 30 int lastone = nums.get(nums.size()-1); 31 nums.set(loc,lastone); 32 map.get(lastone).remove(nums.size()-1); 33 map.get(lastone).add(loc); 34 } 35 nums.remove(nums.size()-1); 36 if(map.get(val).isEmpty()) map.remove(val); 37 return true; 38 } 39 40 /** Get a random element from the collection. */ 41 public int getRandom() { 42 return nums.get(rand.nextInt(nums.size())); 43 } 44 } 45 46 /** 47 * Your RandomizedCollection object will be instantiated and called as such: 48 * RandomizedCollection obj = new RandomizedCollection(); 49 * boolean param_1 = obj.insert(val); 50 * boolean param_2 = obj.remove(val); 51 * int param_3 = obj.getRandom(); 52 */