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)