作者: 负雪明烛
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:

  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);

题目大意

产生一个推特系统,这个推特能关注、发推,解关注,获得信息流。

解题方法

这个题主要是考察自己的工程实践能力。这一块,使用了优先级队列。在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);
*/

参考资料:

  1. https://leetcode.com/problems/design-twitter/discuss/155493/Java-Solution-using-Two-classes-User-and-Tweet-and-using-just-one-Map

日期

2018 年 8 月 28 日 —— 雾霾天
2018 年 12 月 6 日 —— 周四啦!

【LeetCode】355. Design Twitter 解题报告(Python & C++)的更多相关文章

  1. [LeetCode] 355. Design Twitter 设计推特

    Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and ...

  2. leetcode@ [355] Design Twitter (Object Oriented Programming)

    https://leetcode.com/problems/design-twitter/ Design a simplified version of Twitter where users can ...

  3. LeetCode 705 Design HashSet 解题报告

    题目要求 Design a HashSet without using any built-in hash table libraries. To be specific, your design s ...

  4. LeetCode 706 Design HashMap 解题报告

    题目要求 Design a HashMap without using any built-in hash table libraries. To be specific, your design s ...

  5. [leetcode]355. Design Twitter设计实现一个微博系统

    //先定义一个数据结构,代表一条微博,有两个内容:发布者id,微博id(代表微博内容) class TwitterData { int userId; int twitterId; public Tw ...

  6. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  7. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  8. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

  9. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

随机推荐

  1. Linux— file命令 用于辨识文件类型

    Linux file命令用于辨识文件类型. 通过file指令,我们得以辨识该文件的类型. 语法 file [-bcLvz][-f <名称文件>][-m <魔法数字文件>...] ...

  2. 在Linux下搭建nRF51822的开发烧写环境(makefile版)

    http://www.qingpingshan.com/m/view.php?aid=394836

  3. CentOS6安装Zabbix(RPM包)

    1. 系统环境状态 2. 安装zabbix4.0 3. 安装mysql+apache+php环境 4.配置mysql 5.配置zabbix-server 6. 配置apache 7. web安装 1 ...

  4. 30-Container With Most Water-Leetcode

    Given n non-negative integers a1, a2, -, an, where each represents a point at coordinate (i, ai). n ...

  5. Hadoop运行jar包报错java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1

    错误信息: java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1    at org.apache.hadoop.mapre ...

  6. 学习java的第六天

    一.今日收获 1.开始了学习手册第二章的学习 2.了解了java里的常量与变量以及数据类型,与c语言的内容类似 二.今日难题 1.都是基础知识,没有什么难题 三.明日目标 1.继续学习java学习手册 ...

  7. 寻找pair

    给定n个整数使其两两组合成一对pair,例如给定 1 ,2 可以组成的pair为(1,1),(1,2),(2,1),(2,2),然后在这些pair中寻找第k小的pair. 输入第一行包含两个数字,第一 ...

  8. Windows zip版本安装MySQL

    Windows --MySQL zip版本安装记录: step1. 官网download zip包:http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5. ...

  9. android知识点duplicateParentState

    android知识点duplicateParentState 今天要做一个效果,组件RelativeLayout上有两个TextView,这两个TextView具有不同的颜色值,现在要的效果是,当Re ...

  10. JDBC(3):PreparedStatement对象介绍

    一,PreparedStatement介绍 PreperedStatement是Statement的子类,它的实例对象可以通过Connection.preparedStatement()方法获得,相对 ...