[LintCode] Mini Twitter 迷你推特

Implement a simple twitter. Support the following method:

postTweet(user_id, tweet_text). Post a tweet.
getTimeline(user_id). Get the given user‘s most recently 10 tweets posted by himself, order by timestamp from most recent to least recent.
getNewsFeed(user_id). Get the given user‘s most recently 10 tweets in his news feed (posted by his friends and himself). Order by timestamp from most recent to least recent.
follow(from_user_id, to_user_id). from_user_id followed to_user_id.
unfollow(from_user_id, to_user_id). from_user_id unfollowed to to_user_id.

Example
postTweet(1, "LintCode is Good!!!")
>> 1
getNewsFeed(1)
>> [1]
getTimeline(1)
>> [1]
follow(2, 1)
getNewsFeed(2)
>> [1]
unfollow(2, 1)
getNewsFeed(2)
>> []

这道题让我们实现一个迷你推特,具有发布消息,获得时间线,新鲜事,加关注和取消关注等功能,其中获得用户的时间线是返回最新10条推特,而新鲜事是返回最新10条自己的和好友的推特,如果取消关注了,那么返回的新鲜事中就没有取消关注的好友的推特。这是一道蛮有意思的设计题,我们为了简化问题,不会真的去获取系统时间来给推特排序,而是我们使用一个变量order,每发布一条消息,order自增1,这样我们就知道order大的发布的就晚,我们新建一个结构体Node,用来给每个tweet绑定一个order,然后我们写一个从一个Node数组中返回最后10个Node的函数,和一个从Node数组中返回前10个Node的函数,然后我们还需要两个哈希表,一个用来建立每个用户和其所有好友之间的映射,另一个用来建立每个用户和其发布的所有推特之间的映射,另外我们还需要一个变量order来记录发布推特的顺序。

对于postTweet函数,我们首先利用Tweet类提供的create函数建立一个tweet,然后我们看发布者是否在users_tweets里,如果不在添加这个用户,然后将这条推特加到和其映射的数组中,最后返回tweet。

对于getTimeline函数,我们先从该用户的推特集中返回最新的10条推特,然后按时间先后顺序排序,然后再返回即可。

对于getNewsFeed函数,我们先把该用户的推特集中最新10条保存下来,然后遍历其所有的好友,将其好友的最新10条保存下来,然后整个按时间先后顺序排序,返回最新10条即可。

对于follow函数,我们将好友加入用户的好友表里。

对于unfollow函数,我们将好友从用户的好友表里删除。

class MiniTwitter {
public:
    struct Node {
        int order;
        Tweet tweet;
        Node(int o, Tweet t): order(o), tweet(t){}
    };

    vector<Node> getLastTen(vector<Node> t) {
        int last = 10;
        if (t.size() < 10) last = t.size();
        return vector<Node>(t.end() - last, t.end());
    }

    vector<Node> getFirstTen(vector<Node> t) {
        int last = 10;
        if (t.size() < 10) last = t.size();
        return vector<Node>(t.begin(), t.begin() + last);
    }

    MiniTwitter() {
        order = 0;
    }

    // @param user_id an integer
    // @param tweet a string
    // return a tweet
    Tweet postTweet(int user_id, string tweet_text) {
        Tweet tweet = Tweet::create(user_id, tweet_text);
        if (!users_tweets.count(user_id)) users_tweets[user_id] = {};
        ++order;
        users_tweets[user_id].push_back(Node(order, tweet));
        return tweet;
    }

    // @param user_id an integer
    // return a list of 10 new feeds recently
    // and sort by timeline
    vector<Tweet> getNewsFeed(int user_id) {
        vector<Node> t;
        if (users_tweets.count(user_id)) {
            t = getLastTen(users_tweets[user_id]);
        }
        if (friends.count(user_id)) {
            for (auto it : friends[user_id]) {
                if (users_tweets.count(it)) {
                    vector<Node> v = getLastTen(users_tweets[it]);
                    t.insert(t.end(), v.begin(), v.end());
                }
            }
        }
        sort(t.begin(), t.end(), [](const Node &a, const Node &b){return a.order > b.order;});
        vector<Tweet> res;
        t = getFirstTen(t);
        for (auto a : t) {
            res.push_back(a.tweet);
        }
        return res;
    }

    // @param user_id an integer
    // return a list of 10 new posts recently
    // and sort by timeline
    vector<Tweet>  getTimeline(int user_id) {
        vector<Node> t;
        if (users_tweets.count(user_id)) {
            t = getLastTen(users_tweets[user_id]);
        }
        sort(t.begin(), t.end(), [](const Node &a, const Node &b){return a.order > b.order;});
        vector<Tweet> res;
        t = getFirstTen(t);
        for (auto a : t) {
            res.push_back(a.tweet);
        }
        return res;
    }

    // @param from_user_id an integer
    // @param to_user_id an integer
    // from user_id follows to_user_id
    void follow(int from_user_id, int to_user_id) {
        friends[from_user_id].insert(to_user_id);
    }

    // @param from_user_id an integer
    // @param to_user_id an integer
    // from user_id unfollows to_user_id
    void unfollow(int from_user_id, int to_user_id) {
        friends[from_user_id].erase(to_user_id);
    }

private:
    unordered_map<int, set<int>> friends;
    unordered_map<int, vector<Node>> users_tweets;
    int order;
};

参考资料:

http://www.jiuzhang.com/solutions/mini-twitter/

时间: 2024-12-29 17:27:00

[LintCode] Mini Twitter 迷你推特的相关文章

Mini Twitter

Implement a simple twitter. Support the following method: postTweet(user_id, tweet_text). Post a tweet. getTimeline(user_id). Get the given user's most recently 10 tweets posted by himself, order by timestamp from most recent to least recent. getNews

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

[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

Python 提取Twitter转发推文的元素(比如用户名)

CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-24 @author: guaguastd @name: extract_retweet_attributions.py ''' if __name__ == '__main__': # import login, see http://blog.csdn.net/guaguastd/article/details/31706155 from login i

[LeetCode] Mini Parser 迷你解析器

Given a nested list of integers represented as a string, implement a parser to deserialize it. Each element is either an integer, or a list -- whose elements may also be integers or other lists. Note: You may assume that the string is well-formed: St

Twitter 高并发高可用架构

解决 Twitter的“问题”就像玩玩具一样,这是一个很有趣的扩展性比喻.每个人都觉得 Twitter很简单,一个菜鸟架构师随便摆弄一下个可伸缩的 Twitter就有了,就这么简单.然而事实不是这样, Twitter的工程副总裁 Raffi Krikorian细致深入的描述了在 Twitter在可伸缩性上的演化过程,如果你想知道 Twitter的如何工作—从这里开始吧. Twitter发展太快,一切转瞬即过,但 Twitter已经长大了.它从一开始一个在Ruby on Rails上苦苦挣扎的小网

Twitter:难吃的薯条让我们看到大数据未来

Twitter 高管贝恩在都柏林召开的一个峰会上讨论公司营收挑战 上市之后的 Twitter,面临华尔街的用户增长和营收增长的压力.作为一项新的营收来源,Twitter 已经在测试站内购物按钮,有望获得购物分成. 在日前的一次行业会议上,Twitter 负责营收和商业模式的总裁贝恩(AdamBain)对外介绍了 Twitter 一个尚未被开挖的营收富矿,那就是授权企业对用户每日产生的五亿条推文进行大数据挖掘,贝恩还举出了厂商主动联系 Twitter 的例子. 作为负责全球营收的高管,贝恩每天面临

新浪微博产品管培生求职之路——微博发展史(一)

聊起微博,不得不提web2.0.告别了1.0传统的信息门户,web2.0时代新的媒体形式层出不穷,每一个新媒体形式的出现都意味着web2.0的普及和进步,微博就是在这种背景下诞生的.古人云,以史为鉴,可正衣冠.为了一步步走近微博,我们先从历史聊起.纵观新浪微博的发展历史,我将其分为三个阶段: 古代:微博元年,战火纷飞,群雄混战: 近代:杀出血路,战略靠拢,美国敲钟: 现代:后上市时代,稳中求进,何去何从. 本文就先从开山鼻祖twitter开始,讲讲新浪微博的古代史.此文撰与2010年,其中数据并

“大数据“基础知识普及

大数据,官方定义是指那些数据量特别大.数据类别特别复杂的数据集,这种数据集无法用传统的数据库进行存储,管理和处理.大数据的主要特点为数据量大(Volume),数据类别复杂(Variety),数据处理速度快(Velocity)和数据真实性高(Veracity),合起来被称为4V. 大数据中的数据量非常巨大,达到了PB级别.而且这庞大的数据之中,不仅仅包括结构化数据(如数字.符号等数据),还包括非结构化数据(如文本.图像.声音.视频等数据).这使得大数据的存储,管理和处理很难利用传统的关系型数据库去