Implement a simple twitter. Support the following method:數組
postTweet(user_id, tweet_text). Post a tweet.
getTimeline(user_id). Get the given user's most recently 10 tweets posted by himself, order by timestamp from most recent to least recent.
getNewsFeed(user_id). Get the given user's most recently 10 tweets in his news feed (posted by his friends and himself). Order by timestamp from most recent to least recent.
follow(from_user_id, to_user_id). from_user_id followed to_user_id.
unfollow(from_user_id, to_user_id). from_user_id unfollowed to to_user_id.函數
Example
postTweet(1, "LintCode is Good!!!")
>> 1
getNewsFeed(1)
>> [1]
getTimeline(1)
>> [1]
follow(2, 1)
getNewsFeed(2)
>> [1]
unfollow(2, 1)
getNewsFeed(2)
>> [] post
這道題讓咱們實現一個迷你推特,具備發佈消息,得到時間線,新鮮事,加關注和取消關注等功能,其中得到用戶的時間線是返回最新10條推特,而新鮮事是返回最新10條本身的和好友的推特,若是取消關注了,那麼返回的新鮮事中就沒有取消關注的好友的推特。這是一道蠻有意思的設計題,咱們爲了簡化問題,不會真的去獲取系統時間來給推特排序,而是咱們使用一個變量order,每發佈一條消息,order自增1,這樣咱們就知道order大的發佈的就晚,咱們新建一個結構體Node,用來給每一個tweet綁定一個order,而後咱們寫一個從一個Node數組中返回最後10個Node的函數,和一個從Node數組中返回前10個Node的函數,而後咱們還須要兩個哈希表,一個用來創建每一個用戶和其全部好友之間的映射,另外一個用來創建每一個用戶和其發佈的全部推特之間的映射,另外咱們還須要一個變量order來記錄發佈推特的順序。spa
對於postTweet函數,咱們首先利用Tweet類提供的create函數創建一個tweet,而後咱們看發佈者是否在users_tweets裏,若是不在添加這個用戶,而後將這條推特加到和其映射的數組中,最後返回tweet。設計
對於getTimeline函數,咱們先從該用戶的推特集中返回最新的10條推特,而後按時間前後順序排序,而後再返回便可。code
對於getNewsFeed函數,咱們先把該用戶的推特集中最新10條保存下來,而後遍歷其全部的好友,將其好友的最新10條保存下來,而後整個按時間前後順序排序,返回最新10條便可。blog
對於follow函數,咱們將好友加入用戶的好友表裏。排序
對於unfollow函數,咱們將好友從用戶的好友表裏刪除。get
class MiniTwitter { public: struct Node { int order; Tweet tweet; Node(int o, Tweet t): order(o), tweet(t){} }; vector<Node> getLastTen(vector<Node> t) { int last = 10; if (t.size() < 10) last = t.size(); return vector<Node>(t.end() - last, t.end()); } vector<Node> getFirstTen(vector<Node> t) { int last = 10; if (t.size() < 10) last = t.size(); return vector<Node>(t.begin(), t.begin() + last); } MiniTwitter() { order = 0; } // @param user_id an integer // @param tweet a string // return a tweet Tweet postTweet(int user_id, string tweet_text) { Tweet tweet = Tweet::create(user_id, tweet_text); if (!users_tweets.count(user_id)) users_tweets[user_id] = {}; ++order; users_tweets[user_id].push_back(Node(order, tweet)); return tweet; } // @param user_id an integer // return a list of 10 new feeds recently // and sort by timeline vector<Tweet> getNewsFeed(int user_id) { vector<Node> t; if (users_tweets.count(user_id)) { t = getLastTen(users_tweets[user_id]); } if (friends.count(user_id)) { for (auto it : friends[user_id]) { if (users_tweets.count(it)) { vector<Node> v = getLastTen(users_tweets[it]); t.insert(t.end(), v.begin(), v.end()); } } } sort(t.begin(), t.end(), [](const Node &a, const Node &b){return a.order > b.order;}); vector<Tweet> res; t = getFirstTen(t); for (auto a : t) { res.push_back(a.tweet); } return res; } // @param user_id an integer // return a list of 10 new posts recently // and sort by timeline vector<Tweet> getTimeline(int user_id) { vector<Node> t; if (users_tweets.count(user_id)) { t = getLastTen(users_tweets[user_id]); } sort(t.begin(), t.end(), [](const Node &a, const Node &b){return a.order > b.order;}); vector<Tweet> res; t = getFirstTen(t); for (auto a : t) { res.push_back(a.tweet); } return res; } // @param from_user_id an integer // @param to_user_id an integer // from user_id follows to_user_id void follow(int from_user_id, int to_user_id) { friends[from_user_id].insert(to_user_id); } // @param from_user_id an integer // @param to_user_id an integer // from user_id unfollows to_user_id void unfollow(int from_user_id, int to_user_id) { friends[from_user_id].erase(to_user_id); } private: unordered_map<int, set<int>> friends; unordered_map<int, vector<Node>> users_tweets; int order; };
參考資料:string