Insert Delete GetRandom O(1) with Duplicates - Watch the Algorithm Execute, Step by Step
Watching each pointer update and list modification reveals how the algorithm efficiently handles duplicates and maintains index mappings, which is hard to grasp from code alone.
Step 1/11
·Active fill★Answer cell
advance
insert
0
Result: [1]
insert
0
→
1
Result: [1, 1]
insert
0
→
1
→
2
Result: [1, 1, 2]
compare
0
→
1
→
2
Result: [1, 1, 2]
delete
0
→
1
→
2
Result: [1, 1, 2]
detach
0
→
1
→
2
Result: [1, 1, 2]
connect
2
→
1
→
2
Result: [2, 1, 2]
advance
0
→
1
Result: [2, 1]
shrink
0
→
1
Result: [2, 1]
compare
0
→
1
Result: [2, 1]
Key Takeaways
✓ Using a doubly linked list per value to track indices allows O(1) removal of any occurrence of duplicates.
This insight is hard to see from code alone because the linked list structure and its role in index tracking are implicit.
✓ Swapping the last element into the removed index keeps the main array compact and enables O(1) getRandom.
Visualizing the swap clarifies why no shifting is needed and how indices must be updated.
✓ getRandom simply picks a random index from the main list, reflecting the current multiset distribution.
Seeing the random pointer move helps understand the probabilistic output.
Practice
(1/5)
1. You need to design a data structure that supports incrementing and decrementing string keys, and retrieving a key with the maximum or minimum count, all in constant time. Which approach best guarantees O(1) time complexity for all these operations?
easy
A. Using a balanced binary search tree keyed by counts to maintain order of keys
B. Using a hash map to store counts and scanning all keys to find max/min when requested
C. Maintaining a doubly linked list of buckets, each bucket holding keys with the same count, plus hash maps for quick access
D. Using a priority queue to track max and min keys with lazy updates
Solution
Step 1: Understand operation requirements
Increment, decrement, getMaxKey, and getMinKey must all be O(1).
Step 2: Evaluate approaches
Hash map + linear scan (B) is O(n) for max/min. Balanced BST (C) and priority queue (D) have O(log n) operations. Doubly linked list with buckets and hash maps (A) supports O(1) updates and retrievals.
Final Answer:
Option C -> Option C
Quick Check:
Bucket list + hash maps enable O(1) increments, decrements, and max/min retrievals [OK]
Thinking balanced BST or priority queue can achieve O(1) for all operations
2. Consider the following Python code implementing an LRU Cache with capacity 2. After executing the sequence of operations below, what is the return value of cache.get(1)?
After put(1,1) and put(2,2), cache has keys [2 (MRU), 1 (LRU)]. get(1) moves key 1 to MRU, order: [1,2]. put(3,3) evicts LRU key 2, cache: [3,1]. get(2) returns -1 (evicted). put(4,4) evicts LRU key 1, cache: [4,3].
Step 2: Evaluate get(1) after put(4,4)
Key 1 was evicted, so get(1) returns -1.
Final Answer:
Option A -> Option A
Quick Check:
Key 1 evicted after put(4,4), so get(1) -> -1 [OK]
Hint: Remember to update usage order on get and evict LRU on put [OK]
Common Mistakes:
Forgetting to move accessed node to front
Evicting wrong node
Returning wrong value after eviction
3. You need to design a data structure that supports setting values at indices, taking snapshots of the entire array state, and retrieving values at any snapshot efficiently. Which approach best balances time and space complexity for frequent set and get operations?
easy
A. Store full copies of the array on every snapshot to allow O(1) get operations.
B. Maintain a hash map per index storing (snap_id, value) pairs and use binary search to retrieve values for get operations.
C. Use a single global hash map keyed by (index, snap_id) and perform linear search for get operations.
D. Use a segment tree to store snapshots and query values at any snapshot.
Solution
Step 1: Understand problem requirements
The data structure must efficiently support set, snap, and get operations with many snapshots and updates.
Step 2: Evaluate approaches
Storing full snapshots (B) uses too much space and is slow for many snaps. A global hash map with linear search (C) makes get operations slow. Segment trees (D) are complex and not optimal here. Using a hash map per index with binary search (A) allows O(1) amortized set and snap, and O(log m) get, balancing time and space efficiently.
Final Answer:
Option B -> Option B
Quick Check:
Binary search per index enables fast retrieval [OK]
Hint: Binary search per index enables fast retrieval [OK]
Common Mistakes:
Thinking full snapshots are efficient for many snaps
Using linear search for get causes slow queries
4. Consider the following buggy implementation of SnapshotArray. Which line contains the subtle bug that can cause incorrect get results when multiple sets occur before a snap on the same index?
A. Line in snap(): incrementing snap_id before returning
B. Line in __init__(): initializing with (-1, 0) instead of (0, 0)
C. Line in set(): always appending without checking if last snap_id matches
D. Line in get(): using bisect_right instead of bisect_left
Solution
Step 1: Analyze set() method
The set method always appends (snap_id, val) without checking if the last entry has the same snap_id, causing duplicate entries for the same snap_id.
Step 2: Consequence on get()
Duplicate entries for the same snap_id break binary search assumptions and can cause get to return incorrect values.
Final Answer:
Option C -> Option C
Quick Check:
Correct code replaces last entry if snap_id matches [OK]
Hint: Check if last snap_id matches before appending in set() [OK]
Common Mistakes:
Appending blindly causes duplicates
Misunderstanding initialization defaults
5. Suppose the Twitter design is extended so that users can post the same tweet multiple times (tweet reuse allowed). Which modification to the optimal approach is necessary to correctly handle this scenario?
hard
A. Allow multiple TweetNode instances with the same tweetId but different timestamps in the linked list and heap.
B. Use a hash set to track unique tweetIds per user to avoid duplicates in the feed.
C. Modify the heap to store tweetIds only once, ignoring repeated posts of the same tweetId.
D. Disallow posting duplicate tweetIds by rejecting posts with existing tweetIds.
Solution
Step 1: Understand tweet reuse impact
Allowing duplicate tweetIds means multiple posts with same id but different times must be treated as distinct tweets.
Step 2: Adjust data structures
Each post creates a new TweetNode with unique timestamp; heap and linked lists handle duplicates naturally by time ordering.
Final Answer:
Option A -> Option A
Quick Check:
Multiple nodes with same tweetId but different times must be stored separately [OK]
Hint: Treat each post as unique by timestamp, even if tweetId repeats [OK]
Common Mistakes:
Trying to deduplicate tweets in feed incorrectly
Rejecting duplicate posts unnecessarily
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.