[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;
};

本文转自博客园Grandyang的博客,原文链接:迷你推特[LintCode] Mini Twitter ,如需转载请自行联系原博主。

相关文章
|
2月前
|
人工智能 自然语言处理 安全
SOFA AI 网关基于 Higress 的落地实践
SOFA 商业化团队为满足客户 AI 业务的发展需求,基于开源 Higress 内核构建,推出了 SOFA AI 网关,专为 SOFA 场景深度优化、能力增强,是面向 AI 需求的智能网关解决方案。
210 16
|
6月前
|
人工智能 自然语言处理 API
电商API技术文档编写规范白皮书:方法论与行业实践
本文系统阐述电商API接口文档的编写规范与最佳实践,涵盖结构设计、技术语言、开发者体验、版本控制及质量保障等方面,助力企业提升开发效率,构建开放共赢的电商生态。
|
2月前
|
供应链 搜索推荐 API
从0到1掌握1688API:图片搜索获取技巧与避坑指南
1688图片搜索API基于图像识别技术,支持上传JPG/PNG格式图片(Base64或URL),实现同款或相似商品搜索。适用于电商选品、供应链管理等场景,提供价格、销量等多维度筛选,返回商品ID、标题、价格、销量及供应商信息。
拯救你的排版噩梦,搞定Deepseek到WPS的完美转换!
使用DeepSeek生成的文案复制到WPS后排版混乱?别担心,本文教你用LibreOffice解决此问题。首先下载并安装LibreOffice,然后将DeepSeek文案粘贴其中,保存为Word格式,最后用WPS打开,排版完美保留。简单四步,轻松搞定!
|
2月前
|
机器学习/深度学习 人工智能
AI重塑电商拍摄:技术驱动的商业变革——5款AI模特图生成工具技术分析
AI技术正重塑电商拍摄:低成本、高效率生成逼真模特图,支持批量换装、换背景,助力商家快速上架、灵活试错。燕雀光年、Kaiber等工具实测好用,未来AI与实拍将互补共存。
247 0
|
消息中间件 数据采集 Cloud Native
iLogtail 开源贡献人物专访:技术之路无坦途,与社区共同成长
在 iLogtail 开源两周年这一里程碑时刻,我们邀请到了两位社区 Committer 进行分享,揭秘这些开发者如何在日常工作中与 iLogtail 结缘,又如何在业余时间里为项目添砖加瓦,推动其不断向前发展~
346 95
|
存储 算法
数据结构:KMP算法的原理图解和代码解析
数据结构:KMP算法的原理图解和代码解析
蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)
蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)
317 0
|
机器学习/深度学习 数据采集 算法
Python实现Catboost回归模型(CatBoostRegressor算法)项目实战
Python实现Catboost回归模型(CatBoostRegressor算法)项目实战