355. 设计推特

这篇博客介绍了如何使用哈希map、优先队列和链表来设计推特功能,重点在于理解数据结构的原理和应用。作者分享了解题思路,提到虽然思路简单,但实现过程中遇到一些挑战,最终成功解决问题。
摘要由CSDN通过智能技术生成

#355. 设计推特 哈希map+优先队列+链表实现

2020/4/13每日一题打卡√ 难度:中等
题目描述
在这里插入图片描述
在这里插入图片描述
解题思路
这道题其实不难,思路都很简单,但是由于对数据结构不熟悉,一边写一边查那些数据结构的原理,用法还是花了好久。最后还卡在一个很低级的bug,找了好久才找到是哪里出问题了,着实还是太菜辽;这些数据结构是参考了别人的,效率好像还行的样子。

class Twitter {
    private Map<Integer, Tweet> userTweet; //存储每个用户发送的所有推特,推特重新设计了一个类,方便操作,也符合设计的规范
    private Map<Integer, Set<Integer>> userFollow; //存储每个用户关注的人,关注的人列表不需要维持有序,同时为了存取方便O(1)使用hashset,这样也可以避免插入重复的关注的人    
    private PriorityQueue<Tweet> maxHeap;  //用优先队列来按时间顺序存储最近10条推特    
    private static int timestamp = 0;  //时间戳,每发布一条时间+1    
    List<Integer> tweetList = new ArrayList<Integer>();    
    /** Initialize your data structure here. */    
    public Twitter() {  //在这里面初始化数据结构        
    	userTweet = new HashMap<>();        
    	userFollow = new HashMap<>();
    	//优先队列,按时间排序        
    	maxHeap = new PriorityQueue<>((o1, o2) -> -o1.time + o2.time);    	}        
    /** Compose a new tweet. */    
    //发送一条推特,没什么难度,如果有该用户的记录就直接在推特链前加一条
    public void postTweet(int userId, int tweetId) {        
    	Tweet newtw = new Tweet(userId, tweetId);     
    	if(userTweet.containsKey(userId)) {            
    		newtw.next = userTweet.get(userId);        
    	}        
    	else {            
    		newtw.next = null;        
    	}        
    	userTweet.put(userId, newtw);        
    	++timestamp;    
    }        
    /** 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. */    
    //经典的K路合并问题变形,使用优先队列可以简便完成
    public List<Integer> getNewsFeed(int userId) {       
    	maxHeap.clear(); //每次都要清空哦        
    	Set<Integer> follow = userFollow.get(userId); //获取所有这个用户关注的人        
    	if(follow == null) {  //注意用户可能没有关注过人,如果不写这个会报空指针            
    		follow = new HashSet<>();        
    	}        
    	follow.add(userId);        
    	List<Integer> newsFeed = new ArrayList<Integer>(10);      
    	Iterator<Integer> iterator = follow.iterator();        
    	while(iterator.hasNext()){            
    		Tweet ut = userTweet.get(iterator.next());  //用户关注的人的推特列表            
    		int count = 0;    //针对一个关注的人,最多只要比较前十条微博            
    		while(ut != null && count < 10) {                
    			maxHeap.offer(ut);                
    			ut = ut.next;                
    			++count;            
    		}        
    	}        
    	int count = 0;
    	//取优先队列的前十个        
    	while(!maxHeap.isEmpty() && count < 10) {            
    		newsFeed.add(maxHeap.poll().tweetId);            			
    		count++;        
    	}        
    	return newsFeed;    
    }        
    /** Follower follows a followee. If the operation is invalid, it should be a no-op. */    
    public void follow(int followerId, int followeeId) {        
    	if (followerId == followeeId) {  //可能出现自己关注自己的情况          
    		return;        
    	}        
    	if(userFollow.containsKey(followerId)) {            
    		userFollow.get(followerId).add(followeeId);        
    	}        
    	else {            
    		Set<Integer> follow = new HashSet<>();            
    		follow.add(followeeId);            
    		userFollow.put(followerId,follow);        
    	}    
    }        
    /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */    
    public void unfollow(int followerId, int followeeId) {        
    	if (followerId == followeeId) {  //可能出现自己关注自己的情况            
    		return;        
    	}        
    	if(userFollow.containsKey(followerId)) {            
    		Set<Integer> follow = userFollow.get(followerId);            
    		follow.remove(followeeId);        
    	}    
    }    
    class Tweet{  //推特类,表示一条推特,最新发送的放在前面,后发送的在后面        
    	private int userId;        
    	private int tweetId;        
    	private int time;        
    	public Tweet next;        
    	public Tweet(int uid,int tid) {            
    		this.userId = uid;            
    		this.tweetId = tid;            
    		this.time = timestamp;            
    		this.next = null;        
    	}    
    }
   }
/** * Your Twitter object will be instantiated and called as such: * 
	Twitter obj = new Twitter(); * 
	obj.postTweet(userId,tweetId); * 
	List<Integer> param_2 = obj.getNewsFeed(userId); * 
	obj.follow(followerId,followeeId); * 
	obj.unfollow(followerId,followeeId); */

提交结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值