# 0355. Design Twitter ###### tags: `Leetcode` `Medium` `Design` Link: https://leetcode.com/problems/design-twitter/description/ ## 思路 三个map分别存每个user发的tweetIds,每个tweetId发的时间,每个user follow的users 用一个额外的变量timeId记录每个tweet发的时间顺序 getNewsFeed里面我们用一个priority queue 把followee的tweetId都放进去 只留前10个 最后把他们都加进list 一开始加进list的时候其实是倒序 所以需要再花O(1)把它们倒过来 ## Code ```java= class Twitter { Map<Integer, List<Integer>> userToTweet; Map<Integer, Integer> tweetIdToTimeId; Map<Integer, Set<Integer>> userToFollow; int timeId = 0; public Twitter() { userToTweet = new HashMap<>(); tweetIdToTimeId = new HashMap<>(); userToFollow = new HashMap<>(); } public void postTweet(int userId, int tweetId) { if(!userToTweet.containsKey(userId)) userToTweet.put(userId, new ArrayList<>()); userToTweet.get(userId).add(tweetId); tweetIdToTimeId.put(tweetId, timeId++); } public List<Integer> getNewsFeed(int userId) { Queue<Integer> pq = new PriorityQueue<>((a,b)->(tweetIdToTimeId.get(a)-tweetIdToTimeId.get(b))); Set<Integer> followees = userToFollow.getOrDefault(userId, new HashSet<>()); followees.add(userId); for(int followee:followees){ for(int tweetId:userToTweet.getOrDefault(followee, new ArrayList<>())){ pq.add(tweetId); if(pq.size()>10) pq.poll(); } } List<Integer> temp = new ArrayList<>(); while(!pq.isEmpty()){ temp.add(pq.poll()); } List<Integer> ans = new ArrayList<>(); for(int i=temp.size()-1; i>=0; i--){ ans.add(temp.get(i)); } return ans; } public void follow(int followerId, int followeeId) { if(!userToFollow.containsKey(followerId)){ userToFollow.put(followerId, new HashSet<>()); } userToFollow.get(followerId).add(followeeId); } public void unfollow(int followerId, int followeeId) { if(!userToFollow.containsKey(followerId)) return; userToFollow.get(followerId).remove(followeeId); } } ``` ```python= from heapq import * from collections import defaultdict, deque class Twitter: def __init__(self): self.following = defaultdict(set) self.user_tweets = defaultdict(deque) self.time = 0 def postTweet(self, userId: int, tweetId: int) -> None: self.time += 1 tweets = self.user_tweets[userId] tweets.append((self.time, tweetId)) if len(tweets) > 10: tweets.popleft() def getNewsFeed(self, userId: int) -> List[int]: h = [] h.extend(self.user_tweets[userId]) heapify(h) for followeeId in self.following[userId]: tweets = self.user_tweets[followeeId] for i in range(len(tweets)-1, -1, -1): if len(h)<10: heappush(h, tweets[i]) else: if h[0][0] < tweets[i][0]: heappushpop(h, tweets[i]) else: break return [heappop(h)[1] for _ in range(len(h))][::-1] def follow(self, followerId: int, followeeId: int) -> None: self.following[followerId].add(followeeId) def unfollow(self, followerId: int, followeeId: int) -> None: self.following[followerId].discard(followeeId) ```