1 import heapq
 2 import collections
 3 class Twitter:
 4     def __init__(self):
 5         self.followers = collections.defaultdict(set)#key是被关注者,value是关注这个用户的人的集合
 6         self.following = collections.defaultdict(set)#key是用户,value是这个用户关注的人的集合
 7         self.tweetMap = collections.defaultdict(list)#key是用户,value是这个用户自己发的推文的列表
 8         self.tweetHeap = collections.defaultdict(list)#key是用户,value设计这个用户可以看到的推文的列表
 9         self.globalcount = 0
10 
11     def postTweet(self, userId: int, tweetId: int) -> None:
12         self.globalcount -= 1#堆,倒序排列,相当于大顶堆
13         #用户自己发送的推文增加
14         self.tweetMap[userId].append((self.globalcount, tweetId, userId))
15         #用户可以看到的推文增加
16         self.tweetHeap[userId].append((self.globalcount, tweetId, userId))
17         #关注了此当前用户的人,可以看到的推文增加
18         for id in self.followers.get(userId,[]):
19             self.tweetHeap[id].append((self.tweetMap[userId][-1][0], self.tweetMap[userId][-1][1],self.tweetMap[userId][-1][2]))
20 
21     def getNewsFeed(self, userId: int) -> 'List[int]':
22         res = []
23         heap = (list(set(self.tweetHeap[userId])))#当前用户可以查看的推文去重
24         heapq.heapify(heap)#生成大顶堆
25         while heap and len(res) < 10:#取堆顶的最多10条推文
26             item = heapq.heappop(heap)
27             res.append(item[1])
28         return res
29 
30 
31     def follow(self, followerId: int, followeeId: int) -> None:
32         if followerId != followeeId:#如果 关注的不是自己
33             self.following[followerId].add(followeeId)#关注集合增加新用户
34             self.followers[followeeId].add(followerId)#被关注集合增加新用户
35 
36             if (self.tweetMap.get(followeeId)):#当前用户发布过推文
37                 for i in range(len(self.tweetMap[followeeId])):#关注此用户的所有用户的可以看到的推文列表中增加
38                     self.tweetHeap[followerId].append((self.tweetMap[followeeId][i][0], self.tweetMap[followeeId][i][1],self.tweetMap[followeeId][i][2]))
39 
40     def unfollow(self, followerId: int, followeeId: int) -> None:
41         if followeeId in self.following[followerId]:#某用户想要取消关注另一用户,被取消关注的用户是某用户已经关注过的
42             self.following[followerId].discard(followeeId)#从当前用户的关注列表中清除
43             self.followers[followeeId].discard(followerId)#被关注用户的被关注列表清除
44             x = [i for i in self.tweetHeap.get(followerId) if i[2] != followeeId]
45             #循环更新当前用户可以看到的推文列表,将刚才被取消关注的用户的推文去掉
46             self.tweetHeap[followerId] = x

算法思路:设计 + 堆的使用。主要逻辑进行了注释。

参考:https://leetcode.com/problems/design-twitter/discuss/519543/Python-or-getNewsFeed-log(N)-or-Easy-to-understand-or-72ms

posted on 2020-04-09 08:54  Sempron2800+  阅读(226)  评论(0编辑  收藏  举报