[LeetCode] Design Twitter 設計推特


 

Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods:

 

  1. postTweet(userId, tweetId): Compose a new tweet.
  2. getNewsFeed(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.
  3. follow(followerId, followeeId): Follower follows a followee.
  4. unfollow(followerId, followeeId): Follower unfollows a followee.

Example:

Twitter twitter = new Twitter();

// User 1 posts a new tweet (id = 5).
twitter.postTweet(1, 5);

// User 1's news feed should return a list with 1 tweet id -> [5].
twitter.getNewsFeed(1);

// User 1 follows user 2.
twitter.follow(1, 2);

// User 2 posts a new tweet (id = 6).
twitter.postTweet(2, 6);

// User 1's news feed should return a list with 2 tweet ids -> [6, 5].
// Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5.
twitter.getNewsFeed(1);

// User 1 unfollows user 2.
twitter.unfollow(1, 2);

// User 1's news feed should return a list with 1 tweet id -> [5],
// since user 1 is no longer following user 2.
twitter.getNewsFeed(1);

 

這道題讓我們設計個簡單的推特,具有發布消息,獲得新鮮事,添加關注和取消關注等功能。我們需要用兩個哈希表來做,第一個是建立用戶和其所有好友之間的映射,另一個是建立用戶和其所有消息之間的映射。由於獲得新鮮事是需要按時間順序排列的,那么我們可以用一個整型變量cnt來模擬時間點,每發一個消息,cnt自增1,那么我們就知道cnt大的是最近發的。那么我們在建立用戶和其所有消息之間的映射時,還需要建立每個消息和其時間點cnt之間的映射。這道題的主要難點在於實現getNewsFeed()函數,這個函數獲取自己和好友的最近10條消息,我們的做法是用戶也添加到自己的好友列表中,然后遍歷該用戶的所有好友,遍歷每個好友的所有消息,維護一個大小為10的哈希表,如果新遍歷到的消息比哈希表中最早的消息要晚,那么將這個消息加入,然后刪除掉最早的那個消息,這樣我們就可以找出最近10條消息了,參見代碼如下:

 

解法一:

class Twitter {
public:
    Twitter() {
        time = 0;
    }
    
    void postTweet(int userId, int tweetId) {
        follow(userId, userId);
        tweets[userId].insert({time++, tweetId});
    }
    
    vector<int> getNewsFeed(int userId) {
        vector<int> res;
        map<int, int> top10;
        for (auto id : friends[userId]) {
            for (auto a : tweets[id]) {
                top10.insert({a.first, a.second});
                if (top10.size() > 10) top10.erase(top10.begin());
            }
        }
        for (auto a : top10) {
            res.insert(res.begin(), a.second);
        }
        return res;
    }
    
    void follow(int followerId, int followeeId) {
        friends[followerId].insert(followeeId);
    }
    
    void unfollow(int followerId, int followeeId) {
        if (followerId != followeeId) {
            friends[followerId].erase(followeeId);
        }
    }
    
private:
    int time;
    unordered_map<int, unordered_set<int>> friends;
    unordered_map<int, map<int, int>> tweets;
};

 

下面這種方法和上面的基本一樣,就是在保存用戶所有消息的時候,用的是vector<pair<int, int>>,這樣我們可以用priority_queue來幫助我們找出最新10條消息,參見代碼如下:

 

解法二:

class Twitter {
public:
    Twitter() {
        time = 0;
    }
    
    void postTweet(int userId, int tweetId) {
        follow(userId, userId);
        tweets[userId].push_back({time++, tweetId});
    }
    
    vector<int> getNewsFeed(int userId) {
        vector<int> res;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
        for (auto id : friends[userId]) {
            for (auto a : tweets[id]) {
                if (q.size() > 0 && q.top().first > a.first && q.size() > 10) break;
                q.push(a);
                if (q.size() > 10) q.pop();
            }
        }
        while (!q.empty()) {
            res.insert(res.begin(), q.top().second);
            q.pop();
        }
        return res;
    }
    
    void follow(int followerId, int followeeId) {
        friends[followerId].insert(followeeId);
    }
    
    void unfollow(int followerId, int followeeId) {
        if (followerId != followeeId) {
            friends[followerId].erase(followeeId);
        }
    }
    
private:
    int time;
    unordered_map<int, unordered_set<int>> friends;
    unordered_map<int, vector<pair<int, int>>> tweets;
};

 

參考資料:

https://leetcode.com/problems/design-twitter/

https://leetcode.com/problems/design-twitter/discuss/82849/Short-c%2B%2B-solution

https://leetcode.com/problems/design-twitter/discuss/82916/C%2B%2B-solution-with-max-heap

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM