思路见代码,注释很详细
from typing import List
import heapq # 使用堆来筛选最近发表的保温
class Tweet:
"""推文类"""
def __init__(self, tweet_id, cur_time):
self.next = None # 连接下一条推特
self.id = tweet_id
self.time = cur_time # 发表时间,越大发表越近
class User:
"""用户类"""
def __init__(self, user_id):
self.follows = set() # 关注的用户
self.tweet_head = None # 维护当前用户的推文链表
self.id = user_id
self.follows.add(user_id) # 关注自己,便于查找自己和关注的推文信息
def post(self, tweet_id, cur_time):
"""新建推文,头插到推文链表"""
new_tweet = Tweet(tweet_id, cur_time)
new_tweet.next = self.tweet_head
self.tweet_head = new_tweet
def follow(self, followee_id):
"""把某用户添加到关注集合"""
self.follows.add(followee_id)
def unfollow(self, followee_id):
"""从关注集合移除某用户"""
if followee_id != self.id and followee_id in self.follows:
self.follows.remove(followee_id)
class Twitter:
"""推特类"""
def __init__(self):
self.time_stamp = 0 # 时间,这里类似博客编号
self.all_users = {} # 用户Id和用户对象的对应字典
def postTweet(self, userId: int, tweetId: int) -> None:
"""根据ID获取user对象,并创建推文,推文编号+1"""
if userId not in self.all_users:
self.all_users[userId] = User(userId)
user = self.all_users[userId]
user.post(tweetId, self.time_stamp)
self.time_stamp += 1
def getNewsFeed(self, userId: int) -> List[int]:
"""
1.若用户不存在,返回[]
2.若用户存在,找到关注集合的所有用户的第一个推文,放入最小堆中,依次取出最小的节点并把后续节点放入堆中
"""
if userId not in self.all_users:
self.all_users[userId] = User(userId)
return []
else:
user = self.all_users[userId]
heap = []
for followee in user.follows:
cur_tweet_head = self.all_users[followee].tweet_head # 当前用户的推文链表头节点
if cur_tweet_head:
heapq.heappush(heap,[-cur_tweet_head.time, cur_tweet_head]) # 发表时间的负值作为排序关键字
ans = []
while len(heap) > 0:
_, tweet = heapq.heappop(heap)
ans.append(tweet.id)
if tweet.next:
heapq.heappush(heap, [-tweet.next.time, tweet.next])
if len(ans) >= 10:
return ans
return ans
def follow(self, followerId: int, followeeId: int) -> None:
"""关注用户"""
if followerId not in self.all_users:
self.all_users[followerId] = User(followerId)
follower = self.all_users[followerId]
if followeeId not in self.all_users:
self.all_users[followeeId] = User(followeeId)
follower.follow(followeeId)
def unfollow(self, followerId: int, followeeId: int) -> None:
"""取消关注"""
if followerId in self.all_users and followeeId in self.all_users:
follower = self.all_users[followerId]
follower.unfollow(followeeId)