leetcode 力扣 355 设计推特题解 算法题.docx
《leetcode 力扣 355 设计推特题解 算法题.docx》由会员分享,可在线阅读,更多相关《leetcode 力扣 355 设计推特题解 算法题.docx(23页珍藏版)》请在冰豆网上搜索。
leetcode力扣355设计推特题解算法题
题目:
设计推特
设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近10条推文。
实现Twitter类:
•Twitter()初始化简易版推特对象
•voidpostTweet(intuserId,inttweetId)根据给定的tweetId和userId创建一条新推文。
每次调用此函数都会使用一个不同的tweetId。
•ListgetNewsFeed(intuserId)检索当前用户新闻推送中最近 10条推文的ID。
新闻推送中的每一项都必须是由用户关注的人或者是用户自己发布的推文。
推文必须按照时间顺序由最近到最远排序。
•voidfollow(intfollowerId,intfolloweeId)ID为followerId的用户开始关注ID为followeeId的用户。
•voidunfollow(intfollowerId,intfolloweeId)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]]
解释
Twittertwitter=newTwitter();
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]。
推文id6应当在推文id5之前,因为它是在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次
语言:
C++
classTwitter{
structNode{
unordered_setfollowee;
//用链表存储tweetId
listtweet;
};
//getNewsFeed检索的推文的上限以及tweetId的时间戳
intrecentMax,time;
//tweetId对应发送的时间
unordered_maptweetTime;
//每个用户存储的信息
unordered_mapuser;
public:
Twitter(){
time=0;
recentMax=10;
user.clear();
}
//初始化
voidinit(intuserId){
user[userId].followee.clear();
user[userId].tweet.clear();
}
voidpostTweet(intuserId,inttweetId){
if(user.find(userId)==user.end()){
init(userId);
}
//达到限制,剔除链表末尾元素
if(user[userId].tweet.size()==recentMax){
user[userId].tweet.pop_back();
}
user[userId].tweet.push_front(tweetId);
tweetTime[tweetId]=++time;
}
vectorgetNewsFeed(intuserId){
vectorans;ans.clear();
for(list:
:
iteratorit=user[userId].tweet.begin();it!
=user[userId].tweet.end();++it){
ans.emplace_back(*it);
}
for(intfolloweeId:
user[userId].followee){
vectorres;res.clear();
list:
:
iteratorit=user[followeeId].tweet.begin();
inti=0;
//线性归并
while(i<(int)ans.size()&&it!
=user[followeeId].tweet.end()){
if(tweetTime[(*it)]>tweetTime[ans[i]]){
res.emplace_back(*it);
++it;
}else{
res.emplace_back(ans[i]);
++i;
}
//已经找到这两个链表合起来后最近的recentMax条推文
if((int)res.size()==recentMax)break;
}
for(;i<(int)ans.size()&&(int)res.size()for(;it!
=user[followeeId].tweet.end()&&(int)res.size()ans.assign(res.begin(),res.end());
}
returnans;
}
voidfollow(intfollowerId,intfolloweeId){
if(user.find(followerId)==user.end()){
init(followerId);
}
if(user.find(followeeId)==user.end()){
init(followeeId);
}
user[followerId].followee.insert(followeeId);
}
voidunfollow(intfollowerId,intfolloweeId){
user[followerId].followee.erase(followeeId);
}
};
语言:
Java
classTwitter{
privateclassNode{
Setfollowee;
//用链表存储tweetId
LinkedListtweet;
Node(){
followee=newHashSet();
tweet=newLinkedList();
}
}
//getNewsFeed检索的推文的上限以及tweetId的时间戳
privateintrecentMax,time;
//tweetId对应发送的时间
privateMaptweetTime;
//每个用户存储的信息
privateMapuser;
publicTwitter(){
time=0;
recentMax=10;
tweetTime=newHashMap();
user=newHashMap();
}
//初始化
publicvoidinit(intuserId){
user.put(userId,newNode());
}
publicvoidpostTweet(intuserId,inttweetId){
if(!
user.containsKey(userId)){
init(userId);
}
//达到限制,剔除链表末尾元素
if(user.get(userId).tweet.size()==recentMax){
user.get(userId).tweet.remove(recentMax-1);
}
user.get(userId).tweet.addFirst(tweetId);
tweetTime.put(tweetId,++time);
}
publicListgetNewsFeed(intuserId){
LinkedListans=newLinkedList();
for(intit:
user.getOrDefault(userId,newNode()).tweet){
ans.addLast(it);
}
for(intfolloweeId:
user.getOrDefault(userId,newNode()).followee){
continue;
}
LinkedListres=newLinkedList();
inttweetSize=user.get(followeeId).tweet.size();
Iteratorit=user.get(followeeId).tweet.iterator();
inti=0;
intj=0;
intcurr=-1;
//线性归并
if(jcurr=it.next();
while(iif(tweetTime.get(curr)>tweetTime.get(ans.get(i))){
res.addLast(curr);
++j;
if(it.hasNext()){
curr=it.next();
}
}else{
res.addLast(ans.get(i));
++i;
}
//已经找到这两个链表合起来后最近的recentMax条推文
if(res.size()==recentMax){
break;
}
}
}
for(;ires.addLast(ans.get(i));
}
if(jres.addLast(curr);
for(;it.hasNext()&&res.size()res.addLast(it.next());
}
}
ans=newLinkedList(res);
}
returnans;
}
publicvoidfollow(intfollowerId,intfolloweeId){
if(!
user.containsKey(followerId)){
init(followerId);
}
if(!
user.containsKey(followeeId)){
init(followeeId);
}
user.get(followerId).followee.add(followeeId);
}
publicvoidunfollow(intfollowerId,intfolloweeId){
user.getOrDefault(followerId,newNode()).followee.remove(followeeId);
}
}
语言:
Java
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.HashSet;
importjava.util.List;
importjava.util.Map;
importjava.util.PriorityQueue;
importjava.util.Set;
publicclassTwitter{
/**
*用户id和推文(单链表)的对应关系
*/
privateMaptwitter;
/**
*/
privateMap>followings;
/**
*全局使用的时间戳字段,用户每发布一条推文之前+1
*/
privatestaticinttimestamp=0;
/**
*合并k组推文使用的数据结构(可以在方法里创建使用),声明成全局变量非必需,视个人情况使用
*/
privatestaticPriorityQueuemaxHeap;
/**
*Initializeyourdatastructurehere.
*/
publicTwitter(){
followings=newHashMap<>();
twitter=newHashMap<>();
maxHeap=newPriorityQueue<>((o1,o2)->-o1.timestamp+o2.timestamp);
}
/**
*Composeanewtweet.
*/
publicvoidpostTweet(intuserId,inttweetId){
timestamp++;
if(twitter.containsKey(userId)){
TweetoldHead=twitter.get(userId);
TweetnewHead=newTweet(tweetId,timestamp);
newHead.next=oldHead;
twitter.put(userId,newHead);
}else{
twitter.put(userId,newTweet(tweetId,timestamp));
}
}
/**
*Retrievethe10mostrecenttweetidsintheuser'snewsfeed.Eachiteminthenewsfeedmustbepostedbyuserswhotheuserfollowedorbytheuserherself.Tweetsmustbeorderedfrommostrecenttoleastrecent.
*/
publicListgetNewsFeed(intuserId){
//由于是全局使用的,使用之前需要清空
maxHeap.clear();
//如果自己发了推文也要算上
if(twitter.containsKey(userId)){
maxHeap.offer(twitter.get(userId));
}
SetfollowingList=followings.get(userId);
if(followingList!
=null&&followingList.size()>0){
for(IntegerfollowingId:
followingList){
Tweettweet=twitter.get(followingId);
if(tweet!
=null){
maxHeap.offer(tweet);
}
}
}
Listres=newArrayList<>(10);
intcount=0;
while(!
maxHeap.isEmpty()&&count<10){
Tweethead=maxHeap.poll();
res.add(head.id);
//这里最好的操作应该是replace,但是Java没有提供
if(head.next!
=null){
maxHeap.offer(head.next);
}
count++;
}
returnres;
}
/**
*Followerfollowsafollowee.Iftheoperationisinvalid,itshouldbeano-op.
*
*/
publicvoidfollow(intfollowerId,intfolloweeId){
if(followeeId==followerId){
return;
}
SetfollowingList=followings.get(followerId);
if(followingList==null){
Setinit=newHashSet<>();
init.add(followeeId);
followings.put(followerId,init);
}else{
if(followingList.contains(followeeId)){
return;
}
followingList.add(followeeId);
}
}
/**
*Followerunfollowsafollowee.Iftheoperationisinvalid,itshouldbeano-op.
*
*/
publicvoidunfollow(intfollowerId,intfolloweeId){
if(followeeId==followerId){
return;
}
SetfollowingList=followings.get(followerId);
if(followingList==null){
return;
}
//这里删除之前无需做判断,因为查找是否存在以后,就可以删除,反正删除之前都要查找
followingList.remove(followeeId);
}
/**
*推文类,是一个单链表(结点视角)
*/
privateclassTweet{
/**
*推文id
*/
privateintid;
/**
*发推文的时间戳
*/
privateinttimestamp;
privateTweetnext;
publicTweet(intid,inttimestamp){
this.id=id;
this.timestamp=timestamp;
}
}
publicstaticvoidmain(String[]args){
Twittertwitter=newTwitter();
twitter.postTweet(1,1);
Listres1=twitter.getNewsFeed
(1);
System.out.println(res1);
twitter.follow(2,1);
Listres2=twitter.getNewsFeed
(2);
System.out.println(res2);
twitter.unfollow(2,1);
Listres3=twitter.getNewsFeed
(2);
System.out.println(res3);
}
}
语言:
Python
classTwitter:
classNode:
def__init__(self):
self.followee=set()
self.tweet=list()
def__init__(self):
self.time=0
self.recentMax=10
self.tweetTime=dict()
self.user=dict()
defpostTweet(self,userId:
int,tweetId:
int)->None:
ifuserIdnotinself.user:
self.user[userId]=Twitter.Node()
self.user[userId].tweet.append(tweetId)
self.time+=1
self.tweetTime[tweetId]=self.time
defgetNewsFeed(self,userId:
int)-