Post

Leetcode 355. Design Twitter

Explanation for Leetcode 355 - Design Twitter, and its solution in Python.

Problem

Leetcode 355 - Design Twitter

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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]]
Explanation
Twitter twitter = new Twitter();
twitter.postTweet(1, 5); // User 1 posts a new tweet (id = 5).
twitter.getNewsFeed(1);  // User 1's news feed should return a list with 1 tweet id -> [5]. return [5]
twitter.follow(1, 2);    // User 1 follows user 2.
twitter.postTweet(2, 6); // User 2 posts a new tweet (id = 6).
twitter.getNewsFeed(1);  // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5.
twitter.unfollow(1, 2);  // User 1 unfollows user 2.
twitter.getNewsFeed(1);  // User 1's news feed should return a list with 1 tweet id -> [5], since user 1 is no longer following user 2.

Approach

From the given context, postTweet function needs some data structure that could save userId’s post where post consists of arrays

getNewsFeed retrieves 10 most recent tweet. Tweets must be ordered from most recent to least recent, and it should be consisting of user and user followed. Thus we need some other data structure that saves followers per user.

Using all the information given, we can use these:

  • Hash Map (userPost): where key is userId and values are array consisting of (time posted, tweetId). This way we can use heap to get 10 most recent
  • Integer (time): this is to indicate the time use posts the tweet. We have to decrement the time since in python we can get the most recent using heappop the minimum number
  • Hash Map (follower): where key is userId and values are set consisting of followees. This way we don’t have to worry about duplicate follow.

Here is the Python code for the solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Twitter:
    def __init__(self):
        self.userPost = {}
        self.time = 0
        self.follower = {}

    def postTweet(self, userId: int, tweetId: int) -> None:
        arr = self.userPost.get(userId, [])
        self.time -= 1
        arr.append((self.time, tweetId))
        self.userPost[userId] = arr

    def getNewsFeed(self, userId: int) -> List[int]:
        arr = self.userPost.get(userId, []).copy()
        follow = self.follower.get(userId, set())
        
        for f in follow:
            arr += self.userPost.get(f, []).copy()
        
        heapq.heapify(arr)
        posts = []
        for i in range(10):
            if len(arr) == 0:
                return posts
            posts.append(heapq.heappop(arr)[1])
        
        return posts

    def follow(self, followerId: int, followeeId: int) -> None:
        arr = self.follower.get(followerId, set())
        arr.add(followeeId)
        self.follower[followerId] = arr

    def unfollow(self, followerId: int, followeeId: int) -> None:
        arr = self.follower.get(followerId, set())
        if followeeId in arr:
            arr.remove(followeeId)
        self.follower[followerId] = arr

Time Complexity and Space Complexity

Time Complexity:

  • $O(1)$ for initializing, postTeet, follow, unfollow
  • $O(n log n)$ for getNewsFeed

Space Complexity: $O(N * m + N * M + n)$ where $n$ is the total number of followeeIds associated with the userId, $m$ is the maximum number of tweets by any user (at most 10), $N$ is the total number of userIds and $M$ is the maximum number of followees for any user.

This post is licensed under CC BY 4.0 by the author.