[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:
    /** Initialize your data structure here. */
    Twitter() {
        cnt = 0;
    }

    /** Compose a new tweet. */
    void postTweet(int userId, int tweetId) {
        follow(userId, userId);
        tweets[userId].insert({cnt++, tweetId});
    }

    /** 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. */
    vector<int> getNewsFeed(int userId) {
        vector<int> res;
        map<int, int> top10;
        for (auto it = friends[userId].begin(); it != friends[userId].end(); ++it) {
            int t = *it;
            for (auto a = tweets[t].begin(); a != tweets[t].end(); ++a) {
                if (top10.size() > 0 && top10.begin()->first > a->first && top10.size() > 10) break;
                top10.insert({a->first, a->second});
                if (top10.size() > 10) top10.erase(top10.begin());
            }
        }
        for (auto it = top10.rbegin(); it != top10.rend(); ++it) {
            res.push_back(it->second);
        }
        return res;
    }

    /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
    void follow(int followerId, int followeeId) {
        friends[followerId].insert(followeeId);
    }

    /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
    void unfollow(int followerId, int followeeId) {
        if (followerId != followeeId) {
            friends[followerId].erase(followeeId);
        }
    }

private:
    int cnt;
    unordered_map<int, set<int>> friends;
    unordered_map<int, map<int, int>> tweets;
};

下面这种方法和上面的基本一样,就是在保存用户所有消息的时候,用的是vector<pair<int, int>>,这样我们可以用priority_queue来帮助我们找出最新10条消息,参见代码如下:

解法二:

class Twitter {
public:
    /** Initialize your data structure here. */
    Twitter() {
        cnt = 0;
    }

    /** Compose a new tweet. */
    void postTweet(int userId, int tweetId) {
        follow(userId, userId);
        tweets[userId].push_back({cnt++, tweetId});
    }

    /** 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. */
    vector<int> getNewsFeed(int userId) {
        vector<int> res;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
        for (auto it = friends[userId].begin(); it != friends[userId].end(); ++it) {
            for (auto a = tweets[*it].begin(); a != tweets[*it].end(); ++a) {
                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.push_back(q.top().second);
            q.pop();
        }
        reverse(res.begin(), res.end());
        return res;
    }

    /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
    void follow(int followerId, int followeeId) {
        friends[followerId].insert(followeeId);
    }

    /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
    void unfollow(int followerId, int followeeId) {
        if (followerId != followeeId) {
            friends[followerId].erase(followeeId);
        }
    }

private:
    int cnt;
    unordered_map<int, set<int>> friends;
    unordered_map<int, vector<pair<int, int>>> tweets;
};

参考资料:

https://leetcode.com/discuss/107612/my-wa-c-code

https://leetcode.com/discuss/107637/short-c-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

时间: 2024-08-27 07:42:13

[LeetCode] Design Twitter 设计推特的相关文章

[LeetCode] 355. 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: postTweet(userId, tweetId): Compo

LeetCode: Design twitter

Design Twitter [Problem] 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: postTwee

[LeetCode] Design Tic-Tac-Toe 设计井字棋游戏

Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the following rules: A move is guaranteed to be valid and is placed on an empty block.Once a winning condition is reached, no more moves is allowed.A player

[LeetCode] Design HashSet 设计HashSet

Design a HashSet without using any built-in hash table libraries. To be specific, your design should include these functions: add(value): Insert a value into the HashSet. contains(value) : Return whether the value exists in the HashSet or not. remove

[LeetCode] Design HashMap 设计HashMap

Design a HashMap without using any built-in hash table libraries. To be specific, your design should include these functions: put(key, value) : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value.

Android Design 找设计灵感

借鉴下别人超棒的设计与体验 URL:http://huaban.com/boards/1091038/ URL:https://dribbble.com/ 充分的利用github,可以教你的设计师来用,找不同so easy URL:https://github.com/cameronmcefee/Image-Diff-View-Modes/commit/8e95f70c9c47168305970e91021072673d7cdad8 Android Material Design 统一设计语言规

[LeetCode] Design Phone Directory 设计电话目录

Design a Phone Directory which supports the following operations: get: Provide a number which is not assigned to anyone. check: Check if a number is available or not. release: Recycle or release a number. Example: // Init a phone directory containing

[LeetCode] Design Hit Counter 设计点击计数器

Design a hit counter which counts the number of hits received in the past 5 minutes. Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made to the system in chronological order (ie, the times

[LeetCode] Design Snake Game 设计贪吃蛇游戏

Design a Snake game that is played on a device with screen size = width x height. Play the game online if you are not familiar with the game. The snake is initially positioned at the top left corner (0,0) with length = 1 unit. You are given a list of