Skip to content
AI360Xpert
Beta
Difficulty: MediumHeap / Priority Queue

Design Twitter

Problem in Plain English

Design a mini Twitter where users post tweets, follow and unfollow others, and read the 10 most recent tweet ids from themselves and everyone they follow. Recency is decided by posting order rather than by tweet id.

Problem Statement

Design a simplified version of Twitter where users post tweets, follow or unfollow other users, and view the 10 most recent tweets in their news feed.

Implement the Twitter class with void postTweet(userId, tweetId), which records a tweet with a unique tweetId; List getNewsFeed(userId), which returns up to 10 tweet ids from the user and everyone they follow, ordered from most recent to least recent; void follow(followerId, followeeId); and void unfollow(followerId, followeeId). A global posting order decides recency.

Constraints

  • 1 <= userId, followerId, followeeId <= 500
  • 0 <= tweetId <= 10^4
  • All tweet ids are unique.
  • At most 3 * 10^4 calls will be made to postTweet, getNewsFeed, follow and unfollow.
  • The public contract disallows following yourself; these implementations defensively ignore self-follow and self-unfollow.

Examples

Example 1

Input
["Twitter","postTweet","getNewsFeed","follow","postTweet","getNewsFeed","unfollow","getNewsFeed"] [[],[1,5],[1],[1,2],[2,6],[1],[1,2],[1]]
Output
[null,null,[5],null,null,[6,5],null,[5]]

User 1 posts tweet 5, follows user 2, then sees [6,5] after user 2 posts tweet 6. After unfollowing user 2, the feed shrinks back to [5].

Example 2

Input
["Twitter","getNewsFeed","follow","getNewsFeed","unfollow","getNewsFeed"] [[],[1],[1,2],[1],[1,2],[1]]
Output
[null,[],null,[],null,[]]

Neither user has posted. Following and later unfollowing user 2 changes visibility but creates no tweets, so every feed is empty. Querying a previously unseen user must work without creating persistent state.

Example 3

Input
["Twitter","postTweet","postTweet","follow","follow","getNewsFeed","unfollow","getNewsFeed","follow","getNewsFeed"] [[],[2,100],[1,3],[1,2],[1,2],[1],[1,2],[1],[1,2],[1]]
Output
[null,null,null,null,null,[3,100],null,[3],null,[3,100]]

Tweet 3 is newer than 100 despite its smaller ID. Duplicate follows add one author, not two copies of that author's posts. Unfollow hides 100, while following again exposes the same historical tweet; neither operation deletes history.

Intuition

A feed combines your own posting history with the histories of users you currently follow. Give each post an increasing timestamp: tweet IDs are labels, not clocks. In Example 1, tweet 6 has timestamp 1, so it precedes tweet 5 at timestamp 0; unfollowing user 2 hides 6 without deleting it. Each history is already ordered, so a heap can compare only the newest remaining post from each visible author.

Approaches

Collect and Sort

Solution Details

Reveal Collect and Sort: intuition, complexity, and code

Hints

Hint 1
Stamp every tweet with a global counter when it is posted so recency never depends on tweet ids.
Hint 2
A feed merges one sorted tweet list per followed user, which is exactly the merge-k-sorted-lists setup.
Hint 3
Keep one heap entry per followed user and refill from the same user after each pop to walk the lists newest-first.

Edge Cases

  • No posts from any visible author: return [] without registering that user in a map.
  • More than ten visible tweets: return exactly ten, even if all ten come from one author; fewer than ten returns all.
  • Repeated follow and unfollow of a missing relationship are idempotent. Re-following reveals old posts because history is retained.
  • Small tweet IDs can be newer than large IDs. Use the global clock, including when different authors interleave posts.
  • Repeated feeds return the same IDs until posting or visibility changes. A caller modifying the returned list must not corrupt stored posts.
  • Self operations are outside the follow contract but safely ignored; own posts remain visible regardless of follow state.

Common Mistakes and Interview Tips

  • Sorting by tweet ID, or resetting time per author: both confuse labels with global posting order.
  • Adding self directly to a stored follow set during getNewsFeed, or reading missing defaultdict keys: either turns a query into a persistent mutation.
  • Using a list for follows: duplicate follows then duplicate an author's tweets. Use a set and a local self-inclusive copy.
  • Popping the stored history itself during a feed: subsequent reads lose tweets. Use a separate candidate and an integer cursor.
  • After a heap pop, advancing every author or using index+1: only the popped author advances backward to its next older post.
  • Claiming linear heap seeding while calling push repeatedly, or ignoring the copied follow set when most followees have no posts.

Key Takeaway

When each source is already sorted, merging with a heap seeded once per source beats re-sorting the union on every query.