摘要:首先建立按時間戳從大到小排列的,找到中的,出其中在中存在的,把每一個的推特鏈表放入,再從中取頭十條推特的放入結果數組。
Design Twitter Note
建立兩個HashMap,一個存user,一個存tweets。以及整型的時間戳timestamp。
user的k-v pair是userId-follower_set,tweets的k-v pair是userId-tweets_linkedlist,tweets屬于Tweet類,包含time和id兩個參數。
postTweet(userId, tweetId):
首先,對于發推的主體,user,要存放在userMap中,而且user要follow自己,所以,userMap.get(userId).add(userId);
然后,在tweets中找到key值userId,將該用戶所有推特內容放入值域的哈希表中。
getNewsFeed(userId):
首先建立按時間戳從大到小排列的PriorityQueue,找到userMap中的userId,filter出其中在tweet中存在的follower,把每一個follower的推特鏈表放入PriorityQueue,再從PriorityQueue中取頭十條推特的id放入結果數組。
follow(followerId, followeeId):
將followeeId加入userMap中的followerId鍵值。
unfollow(followId, followeeId):
將followeeId從userMap中的followerId鍵值里刪除。
Solutionpublic class Twitter { MapMini Twitter Problem> userMap = new HashMap<>(); Map > tweets = new HashMap<>(); int timestamp = 0; class Tweet { int time; int id; Tweet(int time, int id) { this.time = time; this.id = id; } } public void postTweet(int userId, int tweetId) { if (!userMap.containsKey(userId)) userMap.put(userId, new HashSet<>()); userMap.get(userId).add(userId); if (!tweets.containsKey(userId)) tweets.put(userId, new LinkedList<>()); tweets.get(userId).addFirst(new Tweet(timestamp++, tweetId)); } public List getNewsFeed(int userId) { if (!userMap.containsKey(userId)) return new LinkedList<>(); PriorityQueue feed = new PriorityQueue<>((t1, t2) -> t2.time-t1.time); userMap.get(userId).stream().filter(f -> tweets.containsKey(f)) .forEach(f -> tweets.get(f).forEach(feed::add)); List res = new LinkedList<>(); while (feed.size() > 0 && res.size() < 10) res.add(feed.poll().id); return res; } public void follow(int followerId, int followeeId) { if (!userMap.containsKey(followerId)) userMap.put(followerId, new HashSet<>()); userMap.get(followerId).add(followeeId); } public void unfollow(int followerId, int followeeId) { if (userMap.containsKey(followerId) && followeeId != followerId) userMap.get(followerId).remove(followeeId); } }
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.
postTweet(1, "LintCode is Good!!!") -->> 1 getNewsFeed(1) -->> [1] getTimeline(1) -->> [1] follow(2, 1) getNewsFeed(2) -->> [1] unfollow(2, 1) getNewsFeed(2) -->> []Note
設計一個mini Twitter,剛放出來的幾道系統設計題里,這道題才算是關于設計的題目。
要實現這么五個功能:
發推:需要用戶ID,推特內容,該推特的時間戳; 時間線:需要用戶ID,該用戶的推特集,每條推特的時間戳,比較器; 新鮮事:需要用戶ID,好友ID集合,選定用戶群(用戶ID和所有好友ID)的推特集(選定用戶的推特集,時間戳),比較器; 關注:需要用戶ID,被關注用戶ID,好友ID集合; 取關:需要用戶ID,被關注用戶ID,好友ID集合;
以上,根據功能的要求,確定相關變量。然后選擇適當的數據結構:
已經給出的:Tweet(user_id, text, id, create()),
沒有給出但是需要的:時間戳order,帶時間戳的推特Node,推特集,所有推特集users_tweets,好友集friends,整個系統MiniTwitter,
然后,分析一下具體對象之間的邏輯關系:
Node: 包含Tweet和order,構造Node類;
users_tweets: 包含user_id,和對應id的推特集List
friends: 包含user_id,每個id對應一個好友集Map
這樣就很清楚了,我們需要建立一個包含Tweet和Order的Node類,同時聲明兩個全局變量users_tweets和friends。
然后考慮要求實現的功能。
發推,要用給出的Tweet.create(user_id, tweet_text)函數,然后將集成Tweet和order的Node和對應的user_id放入users_tweets;
時間線,需要從users_tweets中按照Order取出對應user_id的后10個Node,再取出Node.tweet放入結果數組List
新鮮事,需要查看user_id的好友列表,將包括自己的每個人的后10個Node放入List
所以,order也要聲明為全局變量。
繼續,關注好友,添加或查找from_user_id作為friends中的key值,然后對這個key值對應的value,也就是Map
取關好友,和關注好友相同的操作,先從friend中get的from_user_id的key值,再remove對應Map中to_user_id的pair即可。
下面討論以上功能實現需要增加的細節。首先,取出前十個Node,取出后十個Node,需要建立兩個函數getFirstTen()和getLastTen(),對List
最后,在功能函數的前面,進行MiniTweeter()的初始化。
結束~
public class MiniTwitter { class Node { public int order; public Tweet tweet; public Node(int order, Tweet tweet) { this.order = order; this.tweet = tweet; } } class SortByOrder implements Comparator { public int compare(Object obj1,Object obj2) { Node node1 = (Node) obj1; Node node2 = (Node) obj2; if (node1.order < node2.order) return 1; else return -1; } } private Map> friends; private Map > users_tweets; private int order; public List getLastTen(List temp) { int last = 10; if (temp.size() < 10) last = temp.size(); return temp.subList(temp.size() - last, temp.size()); } public List getFirstTen(List temp) { int last = 10; if (temp.size() < 10) last = temp.size(); return temp.subList(0, last); } public MiniTwitter() { // initialize your data structure here. this.friends = new HashMap >(); this.users_tweets = new HashMap >(); this.order = 0; } // @param user_id an integer // @param tweet a string // return a tweet public Tweet postTweet(int user_id, String text) { Tweet tweet = Tweet.create(user_id, text); if (!users_tweets.containsKey(user_id)) users_tweets.put(user_id, new ArrayList ()); order += 1; users_tweets.get(user_id).add(new Node(order, tweet)); return tweet; } // @param user_id an integer // return a list of 10 new feeds recently // and sort by timeline public List getNewsFeed(int user_id) { List temp = new ArrayList (); if (users_tweets.containsKey(user_id)) temp.addAll(getLastTen(users_tweets.get(user_id))); if (friends.containsKey(user_id)) { for (Map.Entry entry : friends.get(user_id).entrySet()) { int user = entry.getKey(); if (users_tweets.containsKey(user)) temp.addAll(getLastTen(users_tweets.get(user))); } } Collections.sort(temp, new SortByOrder()); List res = new ArrayList (); temp = getFirstTen(temp); for (Node node : temp) { res.add(node.tweet); } return res; } // @param user_id an integer // return a list of 10 new posts recently // and sort by timeline public List getTimeline(int user_id) { List temp = new ArrayList (); if (users_tweets.containsKey(user_id)) temp.addAll(getLastTen(users_tweets.get(user_id))); Collections.sort(temp, new SortByOrder()); List res = new ArrayList (); temp = getFirstTen(temp); for (Node node : temp) res.add(node.tweet); return res; } // @param from_user_id an integer // @param to_user_id an integer // from user_id follows to_user_id public void follow(int from_user_id, int to_user_id) { if (!friends.containsKey(from_user_id)) friends.put(from_user_id, new HashMap ()); friends.get(from_user_id).put(to_user_id, true); } // @param from_user_id an integer // @param to_user_id an integer // from user_id unfollows to_user_id public void unfollow(int from_user_id, int to_user_id) { if (friends.containsKey(from_user_id)) friends.get(from_user_id).remove(to_user_id); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65821.html
Problem For a web developer, it is very important to know how to design a web pages size. So, given a specific rectangular web page’s area, your job by now is to design a rectangular web page, whose l...
LeetCode version Problem Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, t...
Problem Given a string s and a string t, check if s is subsequence of t. You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) ...
Problem Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. Example Example:Given...
Problem Find the largest palindrome made from the product of two n-digit numbers. Since the result could be very large, you should return the largest palindrome mod 1337. Example Input: 2Output: 987Ex...
閱讀 3195·2021-11-24 10:30
閱讀 1319·2021-09-30 09:56
閱讀 2390·2021-09-07 10:20
閱讀 2603·2021-08-27 13:10
閱讀 706·2019-08-30 11:11
閱讀 2056·2019-08-29 12:13
閱讀 762·2019-08-26 12:24
閱讀 2902·2019-08-26 12:20