day02 355. 设计推特 [中等]

1.题目描述 355. 设计推特

设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近十条推文。你的设计需要支持以下的几个功能:

postTweet(userId, tweetId): 创建一条新的推文
getNewsFeed(userId): 检索最近的十条推文。每个推文都必须是由此用户关注的人或者是用户自己发出的。推文必须按照时间顺序由最近的开始排序。
follow(followerId, followeeId): 关注一个用户
unfollow(followerId, followeeId): 取消关注一个用户
示例:

Twitter twitter = new Twitter();

// 用户1发送了一条新推文 (用户id = 1, 推文id = 5).
twitter.postTweet(1, 5);

// 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文.
twitter.getNewsFeed(1);

// 用户1关注了用户2.
twitter.follow(1, 2);

// 用户2发送了一个新推文 (推文id = 6).
twitter.postTweet(2, 6);

// 用户1的获取推文应当返回一个列表,其中包含两个推文,id分别为 -> [6, 5].
// 推文id6应当在推文id5之前,因为它是在5之后发送的.
twitter.getNewsFeed(1);

// 用户1取消关注了用户2.
twitter.unfollow(1, 2);

// 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文.
// 因为用户1已经不再关注用户2.
twitter.getNewsFeed(1);

2.思路分析

2.1 这是一个典型和和业务系统设计挂钩的问题,整体没有难度,但需要注意设计良好的字典结构,方便查询和存储

为了便于删减一个人的关注列表,使用字典的方式来存储

2.2 理论上只获取top10个推文,用数组合并的思路来做不是很好,用堆来做更合适

3.debug过程

3.1 两个有序数组合并的代码一开始设计有瑕疵,有数组越界,不能处理某一个为空等问题

3.2 没有很好的处理,自己关注自己,自己不关注自己情况下获取自己的所发推文情况

3.3 我看示例,自以为是文章id会自增,这代表了时间排序大小,跑其他用例的时候发现不是这么回事,需要你自己设计全局时间步变量来记录先后顺序

另:编程的时候要特别注意数组删除遍历游标报错问题

4.最终成绩

执行用时 :144 ms, 在所有 Python 提交中击败了16.67%的用户

内存消耗 :18.7 MB, 在所有 Python 提交中击败了50.00%的用户

5.ac代码(python):

class Twitter(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.user_t_dict = {}
        self.user_f_dict = {}
        self.cur_time = -1

    def postTweet(self, userId, tweetId):
        """
        Compose a new tweet.
        :type userId: int
        :type tweetId: int
        :rtype: None
        """
        ts = self.user_t_dict.setdefault(userId, [])
        self.cur_time += 1
        ts.insert(0, (tweetId, self.cur_time))

    def combine_order_list(self, list1, list2):
        # 合并有序数组为大的有序数组
        idx1 = idx2 = 0
        orderlist = []
        while idx1 < len(list1) and idx2 < len(list2):
            if list1[idx1][1] > list2[idx2][1]:
                orderlist.append(list1[idx1])
                idx1 += 1
            else:
                orderlist.append(list2[idx2])
                idx2 += 1
        orderlist += list1[idx1:]
        orderlist += list2[idx2:]
        return orderlist

    def get_top10_ts(self, tss):
        # 1.先进行相对低效的组合合并思路
        orderlist = []
        for ts in tss:
            orderlist = self.combine_order_list(orderlist, ts)
        result = []
        for one in orderlist[:10]:
            result.append(one[0])
        return result

    def getNewsFeed(self, userId):
        """
        Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
        :type userId: int
        :rtype: List[int]
        """
        f_dict = self.user_f_dict.get(userId)
        tss = []
        if f_dict:
            for user in f_dict:
                ts = self.user_t_dict.get(user, [])
                tss.append(ts)
        if not f_dict or userId not in f_dict:
            tss.append(self.user_t_dict.get(userId, []))
        return self.get_top10_ts(tss)

    def follow(self, followerId, followeeId):
        """
        Follower follows a followee. If the operation is invalid, it should be a no-op.
        :type followerId: int
        :type followeeId: int
        :rtype: None
        """
        f_dict = self.user_f_dict.setdefault(followerId, {})
        f_dict[followeeId] = 1

    def unfollow(self, followerId, followeeId):
        """
        Follower unfollows a followee. If the operation is invalid, it should be a no-op.
        :type followerId: int
        :type followeeId: int
        :rtype: None
        """
        f_dict = self.user_f_dict.get(followerId, {})
        if followeeId in f_dict:
            del f_dict[followeeId]
发布了18 篇原创文章 · 获赞 1 · 访问量 7678

猜你喜欢

转载自blog.csdn.net/leitingdulante/article/details/105498161
今日推荐