PracticeNeetCode ↗LeetCode ↗
Design a simplified social feed supporting: posting a tweet for a user, following/unfollowing another user, and fetching a user's news feed — the 10 most recent tweet ids from people they follow, including their own tweets, most recent first.
postTweet(userId, tweetId): append (time, tweetId) to that user's tweet list.getNewsFeed(userId): gather the last 10 tweets from the user and everyone they follow, then take the 10 most recent overall.follow / unfollow: add or remove the followee from the follower's set (guarding against following yourself).Time: O(1) for post/follow/unfollow, O(F · log 10) for getNewsFeed where F is the number of followees — Space: O(n)
import heapq
from collections import defaultdict
class Twitter:
def __init__(self):
self.time = 0
self.tweets = defaultdict(list) # userId -> [(time, tweetId), ...]
self.follows = defaultdict(set) # userId -> set of followeeIds
def postTweet(self, userId: int, tweetId: int) -> None:
self.tweets[userId].append((self.time, tweetId))
self.time += 1
def getNewsFeed(self, userId: int) -> list[int]:
candidates = []
for uid in self.follows[userId] | {userId}:
candidates.extend(self.tweets[uid][-10:])
top = heapq.nlargest(10, candidates)
return [tweetId for _, tweetId in top]
def follow(self, followerId: int, followeeId: int) -> None:
if followerId != followeeId:
self.follows[followerId].add(followeeId)
def unfollow(self, followerId: int, followeeId: int) -> None:
self.follows[followerId].discard(followeeId)How the solution above works, piece by piece.
time is a global counter; each tweet is stored as (time, tweetId) so newer tweets compare larger.tweets[user] is that user's list in posting order; follows[user] is a set of followees.getNewsFeed: for the user and everyone they follow, take at most the last 10 tweets, then heapq.nlargest(10, …) picks the 10 most recent overall.follow ignores following yourself; unfollow uses discard, so unfollowing someone you don't follow is harmless.Running postTweet(1, 5) then getNewsFeed(1):