zoukankan      html  css  js  c++  java
  • leetcode355

     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

  • 相关阅读:
    深入理解ThreadLocal
    synchronized与Lock的区别与使用
    1亿个数中找出最小的100个数--最小堆
    B+/-Tree原理(mysql索引数据结构)
    深入理解token
    shiro(java安全框架)
    第一次项目上Linux服务器(四:CentOS6下Mysql数据库的安装与配置(转))
    第一次项目上Linux服务器(三:安装Tomcat及相关命令)
    第一次项目上Linux服务器(二:——安装jdk)
    第一次项目上Linux服务器(一:远程连接服务器)
  • 原文地址:https://www.cnblogs.com/asenyang/p/12664487.html
Copyright © 2011-2022 走看看