【LeetCode】355. Design Twitter 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/design-twitter/description/
题目描述
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): Compose a new tweet.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.follow(followerId, followeeId): Follower follows a followee.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);
题目大意
产生一个推特系统,这个推特能关注、发推,解关注,获得信息流。
解题方法
这个题主要是考察自己的工程实践能力。这一块,使用了优先级队列。在Python中,优先级队列其实就是可以使用heapq模块实现。
我提交失误的地方主要在于,取消关注的时候,需要多进行判断,是否存在这个用户、被关注的用户,以及他们之间是否存在关注关系等等。
这些判断在其他的函数中并没有使用到,所以注意细节。
另外,下面的做法好像很复杂,足足有100行。其实可以使用defaultdict等数据结构优化代码,使用排序代替heapq的。按下不表。
代码如下:
class User(object):
"""
User structure
"""
def __init__(self, userId):
self.userId = userId
self.tweets = set()
self.following = set()
class Tweet(object):
"""
Tweet structure
"""
def __init__(self, tweetId, userId, ts):
self.tweetId = tweetId
self.userId = userId
self.ts = ts
def __cmp__(self, other):
#call global(builtin) function cmp for int
return cmp(other.ts, self.ts)
class Twitter(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.ts = 0
self.userMap = dict()
def postTweet(self, userId, tweetId):
"""
Compose a new tweet.
:type userId: int
:type tweetId: int
:rtype: void
"""
if userId not in self.userMap:
self.userMap[userId] = User(userId)
tweet = Tweet(tweetId, userId, self.ts)
self.userMap[userId].tweets.add(tweet)
self.ts += 1
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]
"""
res = list()
que = []
if userId not in self.userMap:
return res
mainUser = self.userMap[userId]
for t in mainUser.tweets:
heapq.heappush(que, t)
for u in mainUser.following:
for t in u.tweets:
heapq.heappush(que, t)
n = 0
while que and n < 10:
res.append(heapq.heappop(que).tweetId)
n += 1
return res
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: void
"""
if followeeId not in self.userMap:
self.userMap[followeeId] = User(followeeId)
if followerId not in self.userMap:
self.userMap[followerId] = User(followerId)
if followerId == followeeId:
return
followee = self.userMap[followeeId]
self.userMap[followerId].following.add(followee)
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: void
"""
if (followerId == followeeId) or (followerId not in self.userMap) or (followeeId not in self.userMap):
return
followee = self.userMap[followeeId]
if followee in self.userMap.get(followerId).following:
self.userMap.get(followerId).following.remove(followee)
# Your Twitter object will be instantiated and called as such:
# obj = Twitter()
# obj.postTweet(userId,tweetId)
# param_2 = obj.getNewsFeed(userId)
# obj.follow(followerId,followeeId)
# obj.unfollow(followerId,followeeId)
C++版本的代码如下:
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<>> q;
for (auto &it : friends[userId]) {
for (auto &a : tweets[it]) {
if (!q.empty() && 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 (followeeId != followerId)
friends[followerId].erase(followeeId);
}
private:
int cnt;
unordered_map<int, set<int>> friends;
unordered_map<int, vector<pair<int, int>>> tweets;
};
/**
* Your Twitter object will be instantiated and called as such:
* Twitter obj = new Twitter();
* obj.postTweet(userId,tweetId);
* vector<int> param_2 = obj.getNewsFeed(userId);
* obj.follow(followerId,followeeId);
* obj.unfollow(followerId,followeeId);
*/
参考资料:
日期
2018 年 8 月 28 日 —— 雾霾天
2018 年 12 月 6 日 —— 周四啦!
【LeetCode】355. Design Twitter 解题报告(Python & C++)的更多相关文章
- [LeetCode] 355. Design Twitter 设计推特
Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and ...
- leetcode@ [355] Design Twitter (Object Oriented Programming)
https://leetcode.com/problems/design-twitter/ Design a simplified version of Twitter where users can ...
- LeetCode 705 Design HashSet 解题报告
题目要求 Design a HashSet without using any built-in hash table libraries. To be specific, your design s ...
- LeetCode 706 Design HashMap 解题报告
题目要求 Design a HashMap without using any built-in hash table libraries. To be specific, your design s ...
- [leetcode]355. Design Twitter设计实现一个微博系统
//先定义一个数据结构,代表一条微博,有两个内容:发布者id,微博id(代表微博内容) class TwitterData { int userId; int twitterId; public Tw ...
- 【LeetCode】120. Triangle 解题报告(Python)
[LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...
- LeetCode 1 Two Sum 解题报告
LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...
- 【LeetCode】Permutations II 解题报告
[题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...
- 【LeetCode】Island Perimeter 解题报告
[LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...
随机推荐
- MariaDB——在Linux中查找数据库路径,并进入数据库
1.直接在命令行运营mysql,如果出现下图,说明数据库路径没有设置到环境变量里. 2.找出数据库路径,可以用ps -ef | grep my 命令,查找后台正在执行的命令任务中,包含my字母开头的所 ...
- Linux— rpm 命令
rpm命令是RPM软件包的管理工具.rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎.逐渐受到其他发行版的采用.RPM ...
- mysql order by 多个字段排序实现组内排序
总结:大组在前,小组在后,计量值再最后,即可实现组内排序:下边是参考别人的具体实例: 工作中需用到order by 后两个字段排序,但结果却产生了一个Bug,以此备录. [1]复现问题场景 为了说明问 ...
- 大规模 K8s 集群管理经验分享 · 上篇
11 月 23 日,Erda 与 OSCHINA 社区联手发起了[高手问答第 271 期 -- 聊聊大规模 K8s 集群管理],目前问答活动已持续一周,由 Erda SRE 团队负责人骆冰利为大家解答 ...
- A Child's History of England.15
And indeed it did. For, the great army landing from the great fleet, near Exeter, went forward, layi ...
- A Child's History of England.43
PART THE SECOND When the King heard how Thomas à Becket had lost his life in Canterbury Cathedral, t ...
- 安全相关,xss
XSS XSS,即 Cross Site Script,中译是跨站脚本攻击:其原本缩写是 CSS,但为了和层叠样式表(Cascading Style Sheet)有所区分,因而在安全领域叫做 XSS. ...
- Oracle—merge into语法
oracle的merge into语法,在这种情况下: 基于某些字段,存在就更新,不存在就插入: 不需要先去判断一下记录是否存在,直接使用merge into merge into 语法: MERGE ...
- C++ 之杂记
今天做了一个题,代码不难,但是编译的时候就恼火,老是报错,也不告诉我错哪了.... 之前的代码是这样的,在main函数中调用这个类的构造函数,就一直报错,但是不知道原因,后来加上了const 就好了. ...
- Java虚拟机(JVM)以及跨平台原理
相信大家已经了解到Java具有跨平台的特性,可以"一次编译,到处运行",在Windows下编写的程序,无需任何修改就可以在Linux下运行,这是C和C++很难做到的. 那么,跨平台 ...