题目:
设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近十条推文。你的设计需要支持以下的几个功能:
1.postTweet(userId, tweetId): 创建一条新的推文
2.getNewsFeed(userId):检索最近的十条推文。每个推文都必须是由此用户关注的人或者是用户自己发出的。推文必须按照时间顺序由最近的开始排序。
3.follow(followerId, followeeId): 关注一个用户
4.unfollow(followerId,followeeId): 取消关注一个用户
简单介绍:
设计推特,题目难度:中等,使用语言:JAVA。
该题的代码量确实非常大,需要花费好几个小时写这一道题目,涉及的知识点也是比较多的。
今天花的时间比较多,不详细阐述思路了,下班。
解题思路:
1.设计两个关系即可,一个是ID和该ID发布的推文关系,另外一个关系是ID和其关注的ID关系。
2.想到使用单链表类来保存推文信息,这道题就迎刃而解了。
3.想到使用Map来映射ID和推文,ID和关注者的关系,这道题的整体思路已经很清晰了
代码部分:
import java.util.*;
public class Twitter {
//定义ID和推文的关系,Tweet为单链表类
private Map<Integer,Tweet> twitter;
//定义ID和关注用户关系
private Map<Integer,Set<Integer>> followings;
//全局变量时间,每次发布新推文时间+1
private static int time=0;
//全局变量优先级队列,合并k组推文单链表
private static PriorityQueue<Tweet> maxHeap;
public Twitter() {
twitter=new HashMap<>();
followings=new HashMap<>();
//最大堆
maxHeap=new PriorityQueue<Tweet>((o1,o2)->o2.time-o1.time);
}
//发布推文,时间+1,推文池+1
public void postTweet(int userId,int tweetId) {
time++;
//该ID已经发过推文
if(twitter.containsKey(userId)) {
Tweet oldHead=twitter.get(userId);
Tweet newHead=new Tweet(tweetId,time);
newHead.next=oldHead;
//关联新映射
twitter.put(userId, newHead);
}
else {
Tweet tw=new Tweet(tweetId,time);
twitter.put(userId,tw);
}
}
//获取最近的10条推文
public List<Integer> getNewsFeed(int userId){
//全局的使用,使用前需要清空
maxHeap.clear();
//加入自己的推文
if(twitter.containsKey(userId)) {
maxHeap.offer(twitter.get(userId));
}
//加入关注ID的推文
Set<Integer> followingList=followings.get(userId);
if(followingList!=null&&followingList.size()>0) {
for(Integer followingId:followingList) {
//如果该ID有发送过推文,则加入最大堆
Tweet tweet=twitter.get(followingId);
if(tweet!=null)
maxHeap.offer(tweet);
}
}
//定义链表
List<Integer> res=new ArrayList<>(10);
int count=0;
while(!maxHeap.isEmpty()&&count<10) {
//移除,并返回队头元素
Tweet head=maxHeap.poll();
//推文ID
res.add(head.id);
if(head.next!=null) {
maxHeap.offer(head.next);
}
count++;
}
return res;
}
//followerId 关注者,followeeId 被关注者
public void follow(int followerId,int followeeId) {
//自己关注自己
if(followerId==followeeId) {
return ;
}
//获取关注列表
Set<Integer> followingList=followings.get(followerId);
if(followingList==null) {
//设置被关注者名单
Set <Integer> init=new HashSet<>();
init.add(followeeId);
followings.put(followerId,init);
}else {
//如果包含被关注者
if(followingList.contains(followeeId)) {
return;
}
else {
followingList.add(followeeId);
}
}
}
public void unfollow(int followerId,int followeeId) {
if(followerId==followeeId) {
return ;
}
//获取关注名单
Set <Integer> followingList=followings.get(followerId);
if(followingList==null) {
return;
}
followingList.remove(followeeId);
}
//单链表Tweet类
static class Tweet{
private int id;
private int time;
private Tweet next;
public Tweet(int id,int time) {
this.id=id;
this.time=time;
}
}
public static void main(String[] args) {
Twitter twitter = new Twitter();
twitter.postTweet(1, 1);
List<Integer> res1 = twitter.getNewsFeed(1);
System.out.println(res1);
twitter.follow(2, 1);
List<Integer> res2 = twitter.getNewsFeed(2);
System.out.println(res2);
twitter.unfollow(2, 1);
List<Integer> res3 = twitter.getNewsFeed(2);
System.out.println(res3);
}
}
结语:
晚安!晚安!晚安!晚安!晚安!晚安!晚安!晚安!晚安!晚安!