355. 设计推特

思路见代码,注释很详细

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)

发布了135 篇原创文章 · 获赞 5 · 访问量 7091

猜你喜欢

转载自blog.csdn.net/qq_27921205/article/details/104481490
355