Twitter class 要包含如下 methods:
void postTweet(int userId, int tweetId) :
userId 的 User 發布了 ID 為 tweetId 的推文。tweetId 必須 unique 。List<Integer> getNewsFeed(int userId) :
userId 的 User 的 news feed 中最近的 10 篇推文。void follow(int followerId, int followeeId) :
followerId 的 User 追蹤 ID 為 followeeId 的 User。void unfollow(int followerId, int followeeId) :
followerId 的 User 取消追蹤 ID 為 followeeId 的 User。
測資的 Input/Output
["Twitter", "postTweet", ....] 或回傳 [null, null, ....] 
首先我們實作 follow 功能。由於 followee 理論上不重複,我們對每個 user 建立一個 set 用於儲存 followee:
def __init__(self):
    self.followees = defaultdict(set)
def follow(self, followerId: int, followeeId: int) -> None:
    self.followees[followerId].add(followeeId)
def unfollow(self, followerId: int, followeeId: int) -> None:
    self.followees[followerId].discard(followeeId)
dict 來儲存對應關係。dict 需要預先判斷該 key 是否存在,若不存在要初始化 set ,若存在則要新增到既有的 set ,較為麻煩,因此此處直接使用 defaultdict 幫助我們自動在該 key 第一次存取時進行初始化,因此我們可以當作 set 已經存在,只要 add / discard 即可。接著我們來實現 post 功能。考慮到 getNewsFeed 會需要抓取最近的推文,但推文沒有保證 ID 越大的則越新,因此我們需要自己實作 timestamp 機制。
def __init__(self):
    self.posts = defaultdict(list)
    self.timestamp = 0
def postTweet(self, userId: int, tweetId: int) -> None:
    self.posts[userId].append((self.timestamp, tweetId))
    self.timestamp += 1
tweetId,還要一併紀錄當前的 timestamp ,此處直接建立 tuple , append 到 list 中。最後實作 getNewsFeed ,要從 User 的貼文與所有 followee 的貼文選出最新的十篇,此處我們可以先將所有人個別發布的最新十篇推文取出,再統一排序,取得真正最新的十篇
 def getNewsFeed(self, userId: int) -> List[int]:
      allTweets = set(self.posts[userId][-10:])
      for i in self.followees[userId]:
          allTweets.update(self.posts[i][-10:])
      return list(map(lambda x: x[1], sorted(allTweets, reverse=True)[:10]))
set 來消除重複貼文sorted 可以幫助我們輕鬆排序,不過 sorted 預設順序為由小到大,因此加上 reverse 參數,改為由大到小,再取前 10 篇推文。(timestamp, tweetId) 的 tuple,此處用 map 取出 tweetId,即是答案。完整 python 實作
class Twitter:
    def __init__(self):
        self.followees = defaultdict(set)
        self.posts = defaultdict(list)
        self.timestamp = 0
        
    def postTweet(self, userId: int, tweetId: int) -> None:
        self.posts[userId].append((self.timestamp, tweetId))
        self.timestamp += 1
        
    def getNewsFeed(self, userId: int) -> List[int]:
        allTweets = set(self.posts[userId][-10:])
        for i in self.followees[userId]:
            allTweets.update(self.posts[i][-10:])
        return list(map(lambda x: x[1], sorted(allTweets, reverse=True)[:10]))
    def follow(self, followerId: int, followeeId: int) -> None:
        self.followees[followerId].add(followeeId)
    def unfollow(self, followerId: int, followeeId: int) -> None:
        self.followees[followerId].discard(followeeId)