Insert Delete GetRandom O(1) - Duplicates allowed - Problem

Imagine you need to build a smart bag that can hold multiple copies of the same item and perform three lightning-fast operations:

  • Insert: Add an item to the bag (even if it already exists)
  • Remove: Take out one copy of a specific item (if it exists)
  • Get Random: Pull out a completely random item, where items with more copies have higher chances of being selected

The challenge? Each operation must work in O(1) average time complexity!

Your task: Implement the RandomizedCollection class that supports duplicates (multiset) with these methods:

  • insert(val) - Returns true if val wasn't present before, false if it was already there
  • remove(val) - Returns true if val was found and removed, false if not found
  • getRandom() - Returns a random element where probability is proportional to frequency

This is the advanced version of the classic RandomizedSet problem, now supporting duplicates!

Input & Output

example_1.py โ€” Basic Operations
$ Input: randomizedCollection = new RandomizedCollection(); randomizedCollection.insert(1); // return true since 1 is not present randomizedCollection.insert(1); // return false since 1 is already present randomizedCollection.insert(2); // return true since 2 is not present randomizedCollection.getRandom(); // return 1 or 2 randomly
โ€บ Output: [null, true, false, true, 1 or 2]
๐Ÿ’ก Note: The collection starts empty. First insert(1) returns true as 1 wasn't present. Second insert(1) returns false as 1 was already there. insert(2) returns true as 2 is new. getRandom() can return either 1 or 2, with 1 having higher probability since it appears twice.
example_2.py โ€” Remove Operations
$ Input: randomizedCollection = new RandomizedCollection(); randomizedCollection.insert(1); // [1], return true randomizedCollection.insert(1); // [1,1], return false randomizedCollection.insert(2); // [1,1,2], return true randomizedCollection.remove(1); // [1,2], return true randomizedCollection.remove(1); // [2], return true randomizedCollection.remove(1); // [2], return false
โ€บ Output: [null, true, false, true, true, true, false]
๐Ÿ’ก Note: After inserting 1,1,2 we have [1,1,2]. First remove(1) removes one copy, leaving [1,2]. Second remove(1) removes the last 1, leaving [2]. Third remove(1) returns false as no 1 exists.
example_3.py โ€” Probability Distribution
$ Input: randomizedCollection = new RandomizedCollection(); randomizedCollection.insert(1); // [1] randomizedCollection.insert(1); // [1,1] randomizedCollection.insert(1); // [1,1,1] randomizedCollection.insert(2); // [1,1,1,2] randomizedCollection.getRandom(); // should return 1 with 75% probability, 2 with 25%
โ€บ Output: [null, true, false, false, true, 1 (75% chance) or 2 (25% chance)]
๐Ÿ’ก Note: The collection contains [1,1,1,2]. Since 1 appears 3 times out of 4 total elements, getRandom() should return 1 with probability 3/4 = 75% and 2 with probability 1/4 = 25%.

Visualization

Tap to expand
๐ŸŽฐ The Smart Lottery MachineLottery Ball Tube (Array)1pos 01pos 12pos 23pos 31pos 4๐Ÿ“‹ Position Catalog (HashMap)Ball 1: {0,1,4}Ball 2: {2}Ball 3: {3}The catalog tells us exactly where each ball number is located in the tube!๐ŸŽฏ Why This Design is Perfectโœ… Add Ball: Drop at end of tube + update catalog = O(1)โœ… Remove Ball: Swap with last + update catalog = O(1)โœ… Random Draw: Pick random tube position = O(1)โœ… Correct Probability: More balls = higher chance!catalog tracks positions
Understanding the Visualization
1
Setup
The machine has a tube to store balls in order and a catalog to track where each number's balls are located
2
Adding Balls
New balls are always added to the end of the tube, and their positions are recorded in the catalog
3
Removing Balls
To remove a ball, we swap it with the last ball in the tube, update the catalog, and remove the last position
4
Random Draw
Pick a random position in the tube and return that ball - higher frequency numbers have proportionally higher chances
Key Takeaway
๐ŸŽฏ Key Insight: By combining array indexing (for instant random access) with hash map position tracking (for instant removal), we achieve O(1) performance for all operations while maintaining proper probability distribution for duplicates!

Time & Space Complexity

Time Complexity
โฑ๏ธ
O(1)

All operations (insert, remove, getRandom) are O(1) average time. Hash map operations and array access are both O(1) average.

n
2n
โœ“ Linear Growth
Space Complexity
O(n)

Need O(n) for the array storing all elements and O(n) for the hash map storing index sets for each unique value

n
2n
โšก Linearithmic Space

Constraints

  • -231 โ‰ค val โ‰ค 231 - 1
  • At most 2 * 105 calls will be made to insert, remove, and getRandom
  • getRandom will not be called if the collection is empty
  • Each test case will have at least one call to insert before any call to getRandom
Asked in
Google 45 Amazon 38 Meta 32 Microsoft 28 Apple 22
89.6K Views
High Frequency
~35 min Avg. Time
1.8K Likes
Ln 1, Col 1
Smart Actions
๐Ÿ’ก Explanation
AI Ready
๐Ÿ’ก Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen