355. Design Twitter

问题:

设计数据结构,使得完成以下功能:

  • 关注用户:
    • void follow(int followerId, int followeeId)
  • 取关用户:
    • void unfollow(int followerId, int followeeId)
  • 某用户发状态:
    • void postTweet(int userId, int tweetId)
  • 取得某用户能查看到的最新10条状态(包含自己+被关注者们):
    • vector<int> getNewsFeed(int userId)
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]]

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.
 

Constraints:

1 <= userId, followerId, followeeId <= 500
0 <= tweetId <= 10^4
All the tweets have unique IDs.
At most 3 * 10^4 calls will be made to postTweet, getNewsFeed, follow, and unfollow.

  

解法:System Design

使用两个数据结构保存数据:

  • 关注关系:user1->{user2,user3....} : user1关注了user2,user3...
    • unordered_map<int, set<int>> fol;
  • 某用户发的状态list:user1->{tweet1, tweet2...}   tweet->{timestamp, tweetId}
    • unordered_map<int, vector<pair<int, int>>> tw;

由于取得最新10条状态,需要按照时间戳排序,优先展示时间较大的。

我们使用priority_queue的最大堆来实现,时间戳作为权值。

 

代码参考:

 1 class Twitter {
 2 public:
 3     unordered_map<int, set<int>> fol;// user: followers list
 4     unordered_map<int, vector<pair<int, int>>> tw;// user: list{time, tweet}
 5     long long timestamp;
 6     /** Initialize your data structure here. */
 7     Twitter() {
 8         timestamp=0;
 9     }
10     
11     /** Compose a new tweet. */
12     void postTweet(int userId, int tweetId) {
13         tw[userId].push_back({timestamp++, tweetId});
14     }
15     
16     /** Retrieve 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 herself. Tweets must be ordered from most recent to least recent. */
17     vector<int> getNewsFeed(int userId) {
18         priority_queue<pair<int,int>> q;//timestamp, tweetId
19         for(auto tweet:tw[userId]) {//add oneself's tweets
20             q.push(tweet);
21         }
22         for(auto followee:fol[userId]) {
23             for(auto tweet:tw[followee]) {//add followees' tweets
24                 q.push(tweet);
25             }
26         }
27         vector<int> res;
28         while(!q.empty() && res.size()<10) {
29             res.push_back(q.top().second);
30             q.pop();
31         }
32         return res;
33     }
34     
35     /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
36     void follow(int followerId, int followeeId) {
37         if(followerId != followeeId)//Ensure: oneself is not in his followers.
38             fol[followerId].insert(followeeId);
39     }
40     
41     /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
42     void unfollow(int followerId, int followeeId) {
43         fol[followerId].erase(followeeId);
44     }
45 };
46 
47 /**
48  * Your Twitter object will be instantiated and called as such:
49  * Twitter* obj = new Twitter();
50  * obj->postTweet(userId,tweetId);
51  * vector<int> param_2 = obj->getNewsFeed(userId);
52  * obj->follow(followerId,followeeId);
53  * obj->unfollow(followerId,followeeId);
54  */

 

posted @ 2021-04-15 17:10  habibah_chang  阅读(37)  评论(0编辑  收藏  举报