二、解题思路
- 建立消息队列
- 我们可以用一个集合来保存某人关注的博主。用哈希表建立起推特ID和这个集合的映射
- 优点
- 采用集合结构,不用考虑重复取关、重复关注的问题,集合结构会帮助我们解决一切
- 建立消息队列,在获取推文更新的时候,根据消息队列里的消息的发出者的ID,一一比对该ID是否在某人的关注博主列表或者为博主自己即可,逻辑简单
- 缺点
- 消息队列成为性能瓶颈。每次获取推文更新,需要到消息队列里逐一比对。当消息队列很长时,需要查找非常大的长度才能找到其中寥寥几条应该获取的消息
- 无法实现完整的面向对象,无法明确划分出某人所属的全部推文
- 建立优先队列
- 将推文分散存储,实现某人所属全部推文的隔离
- 用集合来保存某人关注的博主。用哈希表建立起推特ID和这个集合的映射
- 在获取推文时,由于没有消息队列的有序性,必然要求对推文发出时间做出判断,这就要求建立全局时间
- 获取推文时,要对此人关注博主的集合进行遍历,也就是将此人关注博主所发出的全部消息加载到优先队列里,然后挨个输出,达到10个或者优先队列为空后,完成并返回推文列表
三、解题代码
思路一、建立消息队列
class Twitter
{
private:
vector<pair<int, int>> Msg;
unordered_map<int, unordered_set<int>> Fler;
public:
Twitter()
{
}
void postTweet(int userId, int tweetId)
{
Msg.push_back(make_pair(userId, tweetId));
}
vector<int> getNewsFeed(int userId)
{
vector<int> ret;
auto MsgLen = Msg.size();
for (int count = 0, i = Msg.size() - 1; count < 10 && i >= 0; i--)
{
if (Msg[i].first == userId || Fler[userId].find(Msg[i].first) != Fler[userId].end())
{
count++;
ret.push_back(Msg[i].second);
}
}
return ret;
}
void follow(int followerId, int followeeId)
{
if (Fler[followerId].find(followeeId) == Fler[followerId].end())
{
Fler[followerId].insert(followeeId);
}
}
void unfollow(int followerId, int followeeId)
{
if (Fler[followerId].find(followeeId) != Fler[followerId].end())
{
Fler[followerId].erase(followeeId);
}
}
};
思路二、建立优先队列
class Twitter
{
private:
class Text{
public:
int tweetID;
int time;
Text(int id, int tm){
tweetID = id;
time = tm;
}
friend bool operator < (const Text & a, const Text & b) {
return a.time > b.time;
}
};
int global_time = INT_MAX;
unordered_map<int, list<Text>> HisTweet;
unordered_map<int, unordered_set<int>> Fler;
public:
Twitter()
{
}
void postTweet(int userId, int tweetId)
{
HisTweet[userId].push_front(Text(tweetId, global_time--));
}
vector<int> getNewsFeed(int userId)
{
vector<int> ret;
priority_queue<Text> pq;
for(auto i = HisTweet[userId].begin(); i != HisTweet[userId].end(); i++) pq.push(*i);
for(auto i = Fler[userId].begin(); i != Fler[userId].end(); i++){
for(auto j = HisTweet[*i].begin(); j != HisTweet[*i].end(); j++){
pq.push(*j);
}
}
unsigned short count = 10;
while(count > 0 && !pq.empty()){
auto ins = pq.top();
count--;
pq.pop();
ret.push_back(ins.tweetID);
}
return ret;
}
void follow(int followerId, int followeeId)
{
if(followerId == followeeId) return;
if (Fler[followerId].find(followeeId) == Fler[followerId].end())
Fler[followerId].insert(followeeId);
}
void unfollow(int followerId, int followeeId)
{
if(followerId == followeeId) return;
if (Fler[followerId].find(followeeId) != Fler[followerId].end())
Fler[followerId].erase(followeeId);
}
};
四、运行结果
思路一、建立消息队列
思路二、建立优先队列