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]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章