Imagine building a mini Twitter where users can post tweets and see the most recent tweets from people they follow. How do you efficiently retrieve the top K recent tweets?
Design a simplified version of Twitter where users can post tweets, follow/unfollow other users, and retrieve the 10 most recent tweets in their news feed. Each tweet has a unique ID and a timestamp. Implement the following methods:
- postTweet(userId, tweetId): Compose a new tweet.
- getNewsFeed(userId): Retrieve the 10 most recent tweet IDs in the user's news feed. Tweets must be ordered from most recent to least recent.
- follow(followerId, followeeId): Follower follows a followee.
- unfollow(followerId, followeeId): Follower unfollows a followee.
Assume all tweets are timestamped in the order they are posted.
1 ≤ userId, followerId, followeeId ≤ 10^5Tweet IDs are unique integersAt most 10^5 calls will be made to all methodsEach user can follow at most 10^4 usersgetNewsFeed returns up to 10 tweets
Edge cases: User follows no one and has no tweets → getNewsFeed returns empty listUser follows themselves only → getNewsFeed returns their own tweetsUser unfollows someone they do not follow → no effect
public class Twitter {
public Twitter() {
// Write your solution here
}
public void postTweet(int userId, int tweetId) {
}
public List<Integer> getNewsFeed(int userId) {
return new ArrayList<>();
}
public void follow(int followerId, int followeeId) {
}
public void unfollow(int followerId, int followeeId) {
}
}
class Twitter {
public:
Twitter() {
// Write your solution here
}
void postTweet(int userId, int tweetId) {
}
vector<int> getNewsFeed(int userId) {
return {};
}
void follow(int followerId, int followeeId) {
}
void unfollow(int followerId, int followeeId) {
}
};
class Twitter {
constructor() {
// Write your solution here
}
postTweet(userId, tweetId) {
}
getNewsFeed(userId) {
return [];
}
follow(followerId, followeeId) {
}
unfollow(followerId, followeeId) {
}
}
Coming soon
0/9
Common Bugs to Avoid
Wrong: News feed missing followee tweetsNot including followees' tweets in getNewsFeed or not updating follow relationships.✅ In getNewsFeed, collect tweets from user and all followees before sorting and slicing.
Wrong: News feed includes duplicate tweetsCounting tweets multiple times due to incorrect data structure or logic.✅ Ensure each tweet is stored once and included once in news feed; avoid duplicates in merging.
Wrong: News feed returns more than 10 tweetsNot limiting output size to 10 in getNewsFeed.✅ After sorting tweets by timestamp descending, slice the list to first 10 elements.
Wrong: Unfollow causes error or removes wrong followeesNot checking if follower actually follows followee before unfollowing.✅ Check if followee exists in follower's followees set before removing.
Wrong: Solution times out on large inputsUsing brute force scanning of all tweets instead of heap-based merge.✅ Implement max heap to merge tweets from followees efficiently in O(k log F) time.
✓
Test Cases
Try testing your code with users who have no tweets or followees to catch base cases.
Consider cases where multiple followees post tweets; test merging logic carefully.
Think about how to efficiently merge tweets from many followees without scanning all tweets.
t1_01basic
Input[["postTweet",1,5],["getNewsFeed",1]]
Expected[[5]]
⏱ Performance - must finish in 2000ms
User 1 posts a tweet with ID 5. Their news feed returns this tweet.
💡 Focus on storing tweets per user and retrieving recent ones.
💡 Use a data structure that keeps tweets ordered by timestamp.
💡 Implement getNewsFeed to merge tweets from user and followees, returning top 10.
Why it failed: Returned news feed missing or incorrect tweets. Likely not merging user and followees' tweets correctly or not sorting by recency. Fix by collecting tweets from user and followees, sorting by timestamp descending, and returning top 10.
✓ Correctly returns the user's own tweets in news feed.
User 2 posts tweets 6 and 7. User 1 follows user 2, so their news feed returns tweets 7 and 6 in order.
💡 Remember to update follow relationships before fetching news feed.
💡 Ensure getNewsFeed merges tweets from all followees plus the user.
💡 Sort combined tweets by timestamp descending and return top 10.
Why it failed: News feed missing followee's tweets or not ordered by recency. Fix by including followees' tweets and sorting by timestamp descending before slicing top 10.
✓ Correctly merges and orders tweets from followees and user.
t2_01edge
Input[["getNewsFeed",10]]
Expected[[]]
⏱ Performance - must finish in 2000ms
User 10 has no tweets and follows no one, so news feed is empty.
💡 Check behavior when user has no tweets and no followees.
💡 Ensure getNewsFeed returns empty list if no tweets found.
💡 Return empty list instead of null or error.
Why it failed: Returned non-empty or error for user with no tweets/followees. Fix by returning empty list when no tweets available.
✓ Correctly returns empty news feed for user with no tweets or followees.
Test with 10^5 users and 10 followees for user 100000; must complete getNewsFeed in O(k log F) time within 2s.
💡 Naive scanning of all tweets will time out.
💡 Use a max heap to merge tweets from followees efficiently.
💡 Optimize data structures for O(k log F) retrieval of news feed.
Why it failed: Solution times out due to scanning all tweets or inefficient merges. Fix by implementing heap-based k-way merge for getNewsFeed.
✓ Solution runs within time limits using efficient heap-based merge.
Practice
(1/5)
1. You need to design a system that tracks passengers checking in and out of stations, and efficiently calculates average travel times between stations. Which approach best balances time and space efficiency for frequent queries?
easy
A. Use hash maps to store running totals of travel times and counts per route.
B. Store all trips explicitly and scan them to compute averages on demand.
C. Use dynamic programming to precompute all possible route averages.
D. Use a priority queue to keep track of the shortest travel times per route.
Solution
Step 1: Understand the problem requirements
The system must support frequent check-ins, check-outs, and quick average time queries between stations.
Step 2: Evaluate approaches
Storing all trips (B) leads to slow queries. Dynamic programming (C) is not applicable as routes are dynamic and not fixed. Priority queues (D) do not help compute averages efficiently. Hash maps with running totals (A) allow O(1) updates and queries.
Final Answer:
Option A -> Option A
Quick Check:
Hash maps maintain running sums and counts for O(1) average time queries [OK]
Hint: Running totals enable O(1) average queries [OK]
Common Mistakes:
Thinking storing all trips is efficient for queries
2. What is the time complexity of adding a number and then finding the median using the balanced two heaps approach with lazy deletion for a data stream of size n?
medium
A. O(log n) per addNum and O(log n) per findMedian
B. O(n) per addNum and O(1) per findMedian
C. O(log n) per addNum and O(1) per findMedian
D. O(1) per addNum and O(n) per findMedian
Solution
Step 1: Analyze addNum complexity
Adding a number involves pushing to a heap and balancing heaps, each O(log n) operations.
Step 2: Analyze findMedian complexity
Median is retrieved from the top of heaps without modification, O(1) time.
Final Answer:
Option C -> Option C
Quick Check:
Insertion is O(log n), median retrieval O(1) [OK]
Hint: Heap push/pop are O(log n), median peek is O(1) [OK]
Common Mistakes:
Assuming sorting each query is O(log n)
Confusing addNum with findMedian complexity
3. What is the average time complexity of the remove operation in the optimized Insert Delete GetRandom O(1) with duplicates data structure that uses a hash map of element to linked list nodes and a list of elements?
medium
A. O(n) because we need to find the element's index in the list before removal.
B. O(log n) due to maintaining the linked list structure during removals.
C. O(1) worst-case because linked list removals and hash map lookups are constant time.
D. O(1) average because the hash map provides direct access to an element's node for removal.
Solution
Step 1: Identify data structure operations
Removal uses hash map to get a node reference in O(1) average time, then removes node from doubly linked list in O(1).
Step 2: Clarify average vs worst-case
Hash map lookups are average O(1), but worst-case can degrade. Linked list removal is always O(1). So overall average is O(1).
Final Answer:
Option D -> Option D
Quick Check:
Hash map + linked list enables average O(1) removals [OK]
Hint: Hash map + linked list enables average O(1) removals [OK]
Common Mistakes:
Confusing average and worst-case complexities
Assuming linked list removal is O(log n)
Thinking index search is needed
4. Suppose you want to extend the LRU Cache to support a "reuse" operation that marks an existing key as recently used without retrieving its value. Which modification to the optimal LRU Cache implementation is correct to support this efficiently?
hard
A. On reuse, remove the key from the cache and re-insert it with the same value.
B. Do nothing; reuse is equivalent to get, so no code change is needed.
C. Use a queue instead of a doubly linked list to track usage order for easier reuse.
D. Add a new method that calls _remove and _add on the node corresponding to the key.
Solution
Step 1: Understand reuse operation
Reuse means marking a key as recently used without returning its value, so usage order must be updated.
Step 2: Efficiently update usage order
Calling _remove and _add on the node moves it to the front in O(1) time, correctly updating usage.
Final Answer:
Option D -> Option D
Quick Check:
Reuse requires usage update without value retrieval, done by repositioning node [OK]
Hint: Reuse updates usage order like get but without returning value [OK]
Common Mistakes:
Re-inserting wastes time
Queue can't reorder efficiently
Assuming reuse needs no code change
5. Suppose the skyline problem is extended so that buildings can overlap and have negative heights (e.g., representing underground structures). Which modification to the divide and conquer approach is necessary to correctly handle this variant?
hard
A. Modify the merge step to consider absolute values of heights when computing max height
B. Adjust the merge logic to track both max and min heights at each x-coordinate and merge accordingly
C. No modification needed; the existing merge logic works for negative heights
D. Replace divide and conquer with a brute force height map simulation to handle negative heights
Solution
Step 1: Understand impact of negative heights
Negative heights mean skyline can go below ground, so max height alone is insufficient to represent shape.
Step 2: Modify merge logic accordingly
Need to track both max and min heights at each x to correctly merge skylines with negative and positive heights.
Step 3: Evaluate other options
Using absolute values loses sign info; brute force is inefficient; no modification fails correctness.
Final Answer:
Option B -> Option B
Quick Check:
Tracking both max and min heights handles negative overlaps correctly [OK]
Hint: Negative heights require tracking min and max heights, not just max [OK]
Common Mistakes:
Ignoring negative heights
Using absolute values incorrectly
Assuming no change needed
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.