355. 设计推特
设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近 10 条推文。
实现 Twitter 类:
- Twitter() 初始化简易版推特对象
- void postTweet(int userId, int tweetId) 根据给定的 tweetId 和 userId 创建一条新推文。每次调用此函数都会使用一个不同的 tweetId 。
- List getNewsFeed(int userId) 检索当前用户新闻推送中最近 10 条推文的 ID 。新闻推送中的每一项都必须是由用户关注的人或者是用户自己发布的推文。推文必须 按照时间顺序由最近到最远排序 。
- void follow(int followerId, int followeeId) ID 为 followerId 的用户开始关注 ID 为 followeeId 的用户。
- void unfollow(int followerId, int followeeId) ID 为 followerId 的用户不再关注 ID 为 followeeId 的用户。
示例:
输入
["Twitter", "postTweet", "getNewsFeed", "follow", "postTweet", "getNewsFeed", "unfollow", "getNewsFeed"]
[[], [1, 5], [1], [1, 2], [2, 6], [1], [1, 2], [1]]
输出
[null, null, [5], null, null, [6, 5], null, [5]]
解释
Twitter twitter = new Twitter();
twitter.postTweet(1, 5); // 用户 1 发送了一条新推文 (用户 id = 1, 推文 id = 5)
twitter.getNewsFeed(1); // 用户 1 的获取推文应当返回一个列表,其中包含一个 id 为 5 的推文
twitter.follow(1, 2); // 用户 1 关注了用户 2
twitter.postTweet(2, 6); // 用户 2 发送了一个新推文 (推文 id = 6)
twitter.getNewsFeed(1); // 用户 1 的获取推文应当返回一个列表,其中包含两个推文,id 分别为 -> [6, 5] 。推文 id 6 应当在推文 id 5 之前,因为它是在 5 之后发送的
twitter.unfollow(1, 2); // 用户 1 取消关注了用户 2
twitter.getNewsFeed(1); // 用户 1 获取推文应当返回一个列表,其中包含一个 id 为 5 的推文。因为用户 1 已经不再关注用户 2
提示:
- 1 <= userId, followerId, followeeId <= 500
- 0 <= tweetId <= 104
- 所有推特的 ID 都互不相同
- postTweet、getNewsFeed、follow 和 unfollow 方法最多调用 3 * 104 次
模拟
思路
按照设计好的规则,一步一步来实现
- 初始化Tweet:
用一个数组来保存每个用户的数据(用哈希表更好,方便查找用户),
用户的数据是一个数组[用户id,用户tweet列表数组,关注人数组],
用户的tweet列表结构为[[tweetId,时间]]
- 初始化时间:
因为需要按照时间排序,所以定义一个时间从0开始,每次发送tweet都要让时间++
- 首先是发送数据:
这里我们要先判断一下用户是否存在,若不存在则需要初始化,找到用户后,在用户的[1]位拿到用户tweet列表,然后push一条[tweetId,时间],因为最多只需要展示10条,所以要保证用户tweet列表的最大长度为10
- follow用户:
找到用户,在用户的[2]位置拿到用户的关注人列表,然后再用户的follow中判断是否存在需要关注的人,存在则不需要任何操作,不存在则push关主任的id
- unfollow用户:
同上
- getNewsFeed获取用户的最近10条推特,包含关注人在内的,用时间从大到小排序:
找到用户,在[1]拿到用户的所有推特,
找到用户关注人列表,循环拿出所有id的tweet数据和用户的tweet数据放在一起,并排序
最后截取最新的10条数据
至此我们就完成了我们的tweet设计
var Twitter = function () {
this.TeetList = []
this.time = 0
};
/**
* @param {number} userId
* @param {number} tweetId
* @return {void}
*/
Twitter.prototype.postTweet = function (userId, tweetId) {
var user = this.TeetList.find(item => item[0] === userId)
if (!user) {
user = this.addUser(userId)
}
var userTeetList = user[1]
userTeetList.push([tweetId, this.time])
if(userTeetList.length>10){
user[1] = user[1].slice(-10)
}
this.time++
};
/**
* @param {number} userId
* @return {number[]}
*/
Twitter.prototype.addUser = function (userId) {
var userData = [userId, [], []]
this.TeetList.push(userData)
return userData
}
Twitter.prototype.getUserTeetList = function (user, nums) {
var user = this.TeetList.find(item => item[0] === userId)
if (user) {
} else {
return []
}
}
Twitter.prototype.getNewsFeed = function (userId) {
var user = this.TeetList.find(item => item[0] === userId)
// console.log(this.TeetList)
if (user) {
var userTeetList = user[1]
var userFlow = user[2]
var followTeetList = []
for (var i = 0; i < userFlow.length; i++) {
var followItem = this.TeetList.find(item => item[0] === userFlow[i])
if (followItem) {
var followItemTeetList = followItem[1]
followTeetList.push(...followItemTeetList)
}
}
var allTeetList = [...userTeetList, ...followTeetList]
allTeetList.sort((a, b) => {
return b[1] - a[1]
})
// console.log(allTeetList)
var tenNews = allTeetList.slice(0,10).map(item => item[0])
return tenNews
} else {
return []
}
};
/**
* @param {number} followerId
* @param {number} followeeId
* @return {void}
*/
Twitter.prototype.follow = function (followerId, followeeId) {
var user = this.TeetList.find(item => item[0] === followerId)
if (!user) {
user = this.addUser(followerId)
}
//是否已经关注
if (user[2].includes(followeeId)) return
user[2].push(followeeId)
};
/**
* @param {number} followerId
* @param {number} followeeId
* @return {void}
*/
Twitter.prototype.unfollow = function (followerId, followeeId) {
var user = this.TeetList.find(item => item[0] === followerId)
if (!user) {
user = this.addUser(followerId)
}
//是否已经关注
if (!user[2].includes(followeeId)) return
user[2] = user[2].filter(item => {
return item != followeeId
})
};
/**
* Your Twitter object will be instantiated and called as such:
* var obj = new Twitter()
* obj.postTweet(userId,tweetId)
* var param_2 = obj.getNewsFeed(userId)
* obj.follow(followerId,followeeId)
* obj.unfollow(followerId,followeeId)
*/