Design Twitter

Designing a Simplified Twitter Application

In this article, we explore how to design a simplified version of Twitter, implementing core functionalities such as posting tweets, following and unfollowing users, and retrieving personalized news feeds.

This design focuses on efficiency and simplicity, adhering to the constraints and requirements outlined below.

Problem Description

The goal is to build a lightweight Twitter model that provides the following functionalities:

  1. Post Tweets: Users can post unique tweets identified by a tweet ID.
  2. Follow and Unfollow Users: Users can choose to follow or unfollow other users.
  3. Fetch News Feed: Users can retrieve a news feed consisting of the 10 most recent tweets from themselves and the users they follow.

Methods to Implement

  1. Twitter()
    Initializes the Twitter object. This will set up the necessary data structures to manage users, tweets, and their relationships.

  2. postTweet(int userId, int tweetId)
    Publishes a new tweet with a unique ID, associating it with the specified user.

  3. getNewsFeed(int userId)
    Retrieves up to 10 of the most recent tweets in the user’s personalized news feed. The feed includes tweets from:

    • The user themselves.
    • All users they are currently following.
      Tweets are sorted in reverse chronological order (most recent first).
  4. follow(int followerId, int followeeId)
    Allows a user to follow another user.

  5. unfollow(int followerId, int followeeId)
    Allows a user to stop following another user.

Example 1:
Input:
["Twitter", "postTweet", [1, 10], "postTweet", [2, 20], "getNewsFeed", [1], "getNewsFeed", [2], "follow", [1, 2], "getNewsFeed", [1], "getNewsFeed", [2], "unfollow", [1, 2], "getNewsFeed", [1]]

Output:
[null, null, null, [10], [20], null, [20, 10], [20], null, [10]]

Explanation:
Twitter twitter = new Twitter();
twitter.postTweet(1, 10); // User 1 posts a new tweet with id = 10.
twitter.postTweet(2, 20); // User 2 posts a new tweet with id = 20.
twitter.getNewsFeed(1);   // User 1's news feed should only contain their own tweets -> [10].
twitter.getNewsFeed(2);   // User 2's news feed should only contain their own tweets -> [20].
twitter.follow(1, 2);     // User 1 follows user 2.
twitter.getNewsFeed(1);   // User 1's news feed should contain both tweets from user 1 and user 2 -> [20, 10].
twitter.getNewsFeed(2);   // User 2's news feed should still only contain their own tweets -> [20].
twitter.unfollow(1, 2);   // User 1 follows user 2.
twitter.getNewsFeed(1);   // User 1's news feed should only contain their own tweets -> [10].

Explanation: The output [2,0],[0,2] would also be accepted.

Constraints:

  • 1 <= k <= points.length <= 1000
  • -100 <= points[i][0], points[i][1] <= 100

Approach

Key Idea: Max-Heap Simulation

To efficiently retrieve the two heaviest stones, we use a max-heap. However, Python’s heapq library provides a min-heap implementation by default, so we simulate a max-heap by storing negative values.

Algorithm

Steps

  1. Initialize the Heap: Convert all stone weights to negative and push them into a heap.
  2. Simulation Loop:
    • Pop the two largest elements (smallest in the min-heap due to negative values).
    • If the stones are not equal, compute the new weight and push it back into the heap.
  3. Result:
    • If the heap is empty, return 0.
    • Otherwise, return the absolute value of the remaining stone.

There are mainly Two approach to solve this problem – 

  1. Sorting 
  2. Heap

1. Sorting

  • Time complexityO(n∗m+tlog⁡t) for each getNewsFeed() call and O(1) for remaining methods.
  • Space complexity: O(N∗m+N∗M)

2. Heap

  • Time complexity: O(n) for each getNewsFeed()call and O(1) for remaining methods.
  • Space complexity: O(N∗m+N∗M+n)

More Articles