题目描述
请设计一个简易版本的微博系统,用户可以发微博,关注/取消关注另一个用户,并且可以查看他关注的最近10条微博(包括他自己的)。具体来说,你的设计需要支持如下四种方法:
postTweet(userId, tweetId)
:发布一个新的微博;getNewsFeed(userId)
: 在他自己和他所有关注的用户中,返回最新发布的十条微博。微博需要按照从新到旧的顺序返回。follow(followerId, followeeId)
:关注一个用户;unfollow(followerId, followeeId)
:取消关注一个用户;
样例
Twitter twitter = new Twitter();
// User 1 posts a new tweet (id = 5).
twitter.postTweet(1, 5);
// User 1's news feed should return a list with 1 tweet id -> [5].
twitter.getNewsFeed(1);
// User 1 follows user 2.
twitter.follow(1, 2);
// User 2 posts a new tweet (id = 6).
twitter.postTweet(2, 6);
// 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.getNewsFeed(1);
// User 1 unfollows user 2.
twitter.unfollow(1, 2);
// User 1's news feed should return a list with 1 tweet id -> [5],
// since user 1 is no longer following user 2.
twitter.getNewsFeed(1);
算法
(哈希表) $O(nlogn)$
数据结构:
1. 用unordered_map<int, vector<pair<int,int>>> posts
从一个用户映射到他发布的微博列表,其中pair<int,int>
的first
域存储发布的时间,second
域存储发布微博的id;
2. 用unordered_map<int, unordered_set<int>> follows
从一个用户映射到他的关注列表;`
对于所有操作:
1. postTweet(userId, tweetId)
,首先用posts
找到这个用户发布的微博列表,然后将tweetId
插入该列表中;
2. getNewsFeed(userId)
,首先用follows
找到这个用户所有的关注,然后将他们发布的所有微博存入一个vector
,最后将vector
按时间顺序排序后输出前十个;
3. follow(followerId, followeeId)
,首先用follows
找到followerId
的关注列表,然后将followeeId
插入该列表;
4. unfollow(followerId, followeeId)
,首先用follows
找到followerId
的关注列表,然后将followeeId
从该列表中删除;
时间复杂度分析:
1. 对于postTweet(userId, tweetId)
操作,只有一次哈希表查找操作和一次vector插入操作,时间复杂度是 $O(1)$;
2. 对于getNewsFeed(userId)
操作,需要遍历他所关注的所有微博,再对所有微博排序,时间复杂度是 $O(nlogn)$;
3. 对于follow(followerId, followeeId)
操作,只有一次哈希表查找操作,和一次哈希表插入操作,时间复杂度是 $O(1)$;
4. 对于unfollow(followerId, followeeId)
操作,只有一次哈希表查找操作,和一次哈希表删除操作,时间复杂度是 $O(1)$;
C++ 代码
class Twitter {
public:
/** Initialize your data structure here. */
unordered_map<int,vector<pair<int,int>>> posts;
unordered_map<int,unordered_set<int>> follows;
int id = 0;
Twitter() {
}
/** Compose a new tweet. */
void postTweet(int userId, int tweetId) {
posts[userId].push_back(make_pair(id ++, tweetId));
}
/** 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. */
vector<int> getNewsFeed(int userId) {
vector<pair<int,int>> ps;
for (auto x : posts[userId]) ps.push_back(x);
for (auto follow : follows[userId])
for (auto x : posts[follow])
ps.push_back(x);
sort(ps.rbegin(), ps.rend());
vector<int> res;
for (int i = 0; i < 10 && i < ps.size(); i ++ )
res.push_back(ps[i].second);
return res;
}
/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
void follow(int followerId, int followeeId) {
if (followerId != followeeId)
follows[followerId].insert(followeeId);
}
/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
void unfollow(int followerId, int followeeId) {
follows[followerId].erase(followeeId);
}
};
/**
* Your Twitter object will be instantiated and called as such:
* Twitter obj = new Twitter();
* obj.postTweet(userId,tweetId);
* vector<int> param_2 = obj.getNewsFeed(userId);
* obj.follow(followerId,followeeId);
* obj.unfollow(followerId,followeeId);
*/
这题我写过两三次,每次都写不对,看了Y总的,一次AC,感谢
sort(ps.rbegin(), ps.rend());
还可以这样从大到小排序? 神奇啊对滴。