原题链接在这里:https://leetcode.com/problems/insert-delete-getrandom-o1-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();
题解:
用set来保存val的所有index.
Time Complexity: insert, O(1). remove, O(1). getRandom, O(1).
Space: O(n).
AC Java:
1 class RandomizedCollection { 2 ArrayList<Integer> list; 3 HashMap<Integer, LinkedHashSet<Integer>> numToInds; 4 5 /** Initialize your data structure here. */ 6 public RandomizedCollection() { 7 list = new ArrayList<>(); 8 numToInds = new HashMap<>(); 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 contains = numToInds.containsKey(val); 14 if(!contains){ 15 numToInds.put(val, new LinkedHashSet<Integer>()); 16 } 17 18 numToInds.get(val).add(list.size()); 19 list.add(val); 20 return contains; 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 if(!numToInds.containsKey(val) || numToInds.get(val).size() == 0){ 26 return false; 27 } 28 29 LinkedHashSet<Integer> lhs = numToInds.get(val); 30 int ind = lhs.iterator().next(); 31 lhs.remove(ind); 32 int last = list.get(list.size() - 1); 33 list.set(ind, last); 34 numToInds.get(last).add(ind); 35 numToInds.get(last).remove(list.size() - 1); 36 list.remove(list.size() - 1); 37 return true; 38 } 39 40 /** Get a random element from the collection. */ 41 public int getRandom() { 42 Random rand = new Random(); 43 return list.get(rand.nextInt(list.size())); 44 } 45 } 46 47 /** 48 * Your RandomizedCollection object will be instantiated and called as such: 49 * RandomizedCollection obj = new RandomizedCollection(); 50 * boolean param_1 = obj.insert(val); 51 * boolean param_2 = obj.remove(val); 52 * int param_3 = obj.getRandom(); 53 */