C# || How To Implement RandomizedCollection – Insert Delete GetRandom O(1) Duplicates Allowed Using C#
The following is a module with functions which demonstrates how to implement RandomizedCollection – Insert Delete GetRandom O(1) Duplicates Allowed using C#.
1. RandomizedCollection – Problem Statement
Implement the RandomizedCollection class:
- RandomizedCollection() Initializes the RandomizedCollection object.
- bool insert(int val) Inserts an item val into the multiset if not present. Returns true if the item was not present, false otherwise.
- bool remove(int val) Removes an item val from the multiset if present. Returns true if the item was present, false otherwise. Note that if val has multiple occurrences in the multiset, we only remove one of them.
- int getRandom() Returns a random element from the current multiset of elements (it’s guaranteed that at least one element exists when this method is called). The probability of each element being returned is linearly related to the number of same values the multiset contains.
You must implement the functions of the class such that each function works in average O(1) time complexity.
Example 1:
Input
Input
["RandomizedCollection", "insert", "insert", "insert", "getRandom", "remove", "getRandom"]
[[], [1], [1], [2], [], [1], []]
Output
[null, true, false, true, 2, true, 1]Explanation
RandomizedCollection randomizedCollection = new RandomizedCollection();
randomizedCollection.insert(1); // return True. Inserts 1 to the collection. Returns true as the collection did not contain 1.
randomizedCollection.insert(1); // return False. Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
randomizedCollection.insert(2); // return True. Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
randomizedCollection.getRandom(); // getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
randomizedCollection.remove(1); // return True. Removes 1 from the collection, returns true. Collection now contains [1,2].
randomizedCollection.getRandom(); // getRandom should return 1 and 2 both equally likely.
2. RandomizedCollection – Solution
The following is a solution which demonstrates how to implement RandomizedCollection – Insert Delete GetRandom O(1) Duplicates Allowed.
The main idea of this solution is to use a list to store the values added, and use a map to determine if an item has been added already.
The map is also used to store the list index of the added item. This makes it so we know which index to work with when we want to remove an item from the list. The indexes of the added items are stored using a set.
To ensure proper removal, we ‘swap’ places of the value to remove with the last item in the list. This makes it so only the last item in the list is always the index to have items removed from.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 21, 2021 // Taken From: http://programmingnotes.org/ // File: Solution.cs // Description: Demonstrates how to implement RandomizedCollection // ============================================================================ public class RandomizedCollection { // For randomizing the list private Random r; // To determine if an item has been added, and store its list index private Dictionary<int, HashSet<int>> map; // To store the items added private List<int> values; public RandomizedCollection() { r = new Random(); map = new Dictionary<int, HashSet<int>>(); values = new List<int>(); } // Inserts a value to the set. Returns true if the set did not already contain the specified element public bool Insert(int val) { var result = false; // Determine if item exists in map if (!map.ContainsKey(val)) { map[val] = new HashSet<int>(); result = true; } // Add value to the list values.Add(val); // Save the value with its list index to the set map[val].Add(values.Count - 1); return result; } // Removes a value from the set. Returns true if the set contained the specified element public bool Remove(int val) { // Determine if item exists in map if (!map.ContainsKey(val)) { return false; } // Get the last item index var lastItemIndex = values.Count - 1; // Get the first index in the set. // This the current index for the item to remove var itemToRemoveIndex = map[val].First(); // Remove this index from the set map[val].Remove(itemToRemoveIndex); // 'Swap' places of the last item in the list with the item to remove if (itemToRemoveIndex != lastItemIndex) { // Get the last index for the item at the end var needToModifyItem = values[lastItemIndex]; // 'Swap' places of the last item in the list with the item to be removed values[itemToRemoveIndex] = needToModifyItem; // Remove the previous index and add its new index map[needToModifyItem].Add(itemToRemoveIndex); map[needToModifyItem].Remove(lastItemIndex); } // Remove the previous index from the list values.RemoveAt(lastItemIndex); // Remove the value from the map if there are no more entries in the set if (map[val].Count == 0) { map.Remove(val); } return true; } // Get a random element from the set public int GetRandom() { var randomIndex = r.Next(0, values.Count); return values[randomIndex]; } }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Once compiled, you should get this as your output for the example cases:
[null,true,false,true,2,true,2]
Leave a Reply