Posts Design Twitter
Post
Cancel

Design Twitter

Problem Description

Design a simplified version of Twitter where users can post tweets, follow/unfollow another user, and is able to see the 10 most recent tweets in the user’s news feed.

Implement the Twitter class:

  • Twitter() Initializes your twitter object.
  • void postTweet(int userId, int tweetId) Composes a new tweet with ID tweetId by the user userId. Each call to this function will be made with a unique tweetId.
  • List getNewsFeed(int userId) Retrieves the 10 most recent tweet IDs in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user themself. Tweets must be ordered from most recent to least recent.
  • void follow(int followerId, int followeeId) The user with ID followerId started following the user with ID followeeId.
  • void unfollow(int followerId, int followeeId) The user with ID followerId started unfollowing the user with ID followeeId.

leetcode

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class Twitter {

    //list of twitter users    
    Map<Integer, User> users;

    //mapping of userId with the User object
    public Twitter() {
        users = new HashMap<>();
    }
    
    public void postTweet(int userId, int tweetId) {

        //if existing user    
        if(users.containsKey(userId)){
            
            //get user object
            User user = users.get(userId);

            //create tweet object and increase the time for next tweet
            Tweet tweet = new Tweet(tweetId); Tweet.time++;

            //add the tweet to this user
            user.tweets.add(tweet);

        //if non-existing user
        }else{
            
            //create a new user with the input userId
            User user = new User(userId);

            //create tweeet object and increase the time for next tweet
            Tweet tweet = new Tweet(tweetId); Tweet.time++;

            //add the tweet to this user
            user.tweets.add(tweet);

            //add the user to list of users
            users.put(userId, user);
        }

    }
    
    public List<Integer> getNewsFeed(int userId) {

        //min heap based on timestamp
        //latest tweets will be at the top
        PriorityQueue<Tweet> pq = new PriorityQueue<>(); 

        //if the user is not already present, return empty
        if(!users.containsKey(userId)) return new ArrayList<>();

        //otherwise, get the user object
        User user = users.get(userId);
        //get the userId that this user is following
        Set<Integer> followings = user.following;

        //loop through followings list
        for(Integer followerId: followings){
            
            //get following user
            User follower = users.get(followerId);
            //get his tweets
            List<Tweet> tweets = follower.tweets;

            //add all tweets to min heap
            for(Tweet t: tweets){
                pq.add(t);
            }   

        }

        //answer list containing latest 10 tweets
        List<Integer> latestTweetId = new ArrayList<>();
        int s = 0;

        //get the latest 10 tweets from heap
        while(s<10 && !pq.isEmpty()){
            latestTweetId.add(pq.poll().tweetId);
            s++;
        }

        return latestTweetId;

    }
    
    public void follow(int followerId, int followeeId) {
        
        //handle the user where followerId or followeeId in not in the list of users
        if(!users.containsKey(followerId)){
            users.put(followerId, new User(followerId));
        }

        if(!users.containsKey(followeeId)){
            users.put(followeeId, new User(followeeId));
        }

        //get the user
        User user = users.get(followerId);

        //add the follower for that user
        user.following.add(followeeId);

    }
    
    public void unfollow(int followerId, int followeeId) {

        //get the user object
        User user = users.get(followerId);

        //remove followee for that user
        user.following.remove(followeeId);
    }
}

class User{

    int userId;
    List<Tweet> tweets;
    Set<Integer> following;

    //create new user
    User(Integer userId){
        this.userId = userId;
        tweets = new ArrayList<>();
        following = new HashSet<>();
        following.add(userId);//the user is its own follower
    }
}

class Tweet implements Comparable<Tweet>{

    int tweetId;
    int timestamp;

    public static int time = 0; //will use this to track timestamp for tweets

    Tweet(int tweetId){
        this.tweetId = tweetId;
        this.timestamp = Tweet.time;
    }

    public int compareTo(Tweet t2){
        if(this.timestamp == t2.timestamp) return 0;
        //if tweet1.timestamp > tweet2.timestamp
        //=> tweet1 is latest when compared to tweet2
        //=> we want tweet1 before tweet2 in ascending order so that we can add it to min heap
        if(this.timestamp > t2.timestamp) return -1; 
        else return 1;
    }

}

/**
 * Your Twitter object will be instantiated and called as such:
 * Twitter obj = new Twitter();
 * obj.postTweet(userId,tweetId);
 * List<Integer> param_2 = obj.getNewsFeed(userId);
 * obj.follow(followerId,followeeId);
 * obj.unfollow(followerId,followeeId);
 */
This post is licensed under CC BY 4.0 by the author.