import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;public class Twitter {/*** 用戶 id 和推文(單鏈表)的對(duì)應(yīng)關(guān)系*/private Map<Integer, Tweet> twitter;/*** 用戶 id 和他關(guān)注的用戶列表的對(duì)應(yīng)關(guān)系*/private Map<Integer, Set<Integer>> followings;/*** 全局使用的時(shí)間戳字段,用戶每發(fā)布一條推文之前 + 1*/private static int timestamp = 0;/*** 合并 k 組推文使用的數(shù)據(jù)結(jié)構(gòu)(可以在方法里創(chuàng)建使用),聲明成全局變量非必需,視個(gè)人情況使用*/private static PriorityQueue<Tweet> maxHeap;/*** Initialize your data structure here.*/public Twitter() {followings = new HashMap<>();twitter = new HashMap<>();maxHeap = new PriorityQueue<>((o1, o2) -> -o1.timestamp + o2.timestamp);}/*** Compose a new tweet.*/public void postTweet(int userId, int tweetId) {timestamp++;if (twitter.containsKey(userId)) {Tweet oldHead = twitter.get(userId);Tweet newHead = new Tweet(tweetId, timestamp);newHead.next = oldHead;twitter.put(userId, newHead);} else {twitter.put(userId, new Tweet(tweetId, 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.*/public List<Integer> getNewsFeed(int userId) {// 由于是全局使用的,使用之前需要清空maxHeap.clear();// 如果自己發(fā)了推文也要算上if (twitter.containsKey(userId)) {maxHeap.offer(twitter.get(userId));}Set<Integer> followingList = followings.get(userId);if (followingList != null && followingList.size() > 0) {for (Integer followingId : followingList) {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();res.add(head.id);// 這里最好的操作應(yīng)該是 replace,但是 Java 沒(méi)有提供if (head.next != null) {maxHeap.offer(head.next);}count++;}return res;}/*** Follower follows a followee. If the operation is invalid, it should be a no-op.** @param followerId 發(fā)起關(guān)注者 id* @param followeeId 被關(guān)注者 id*/public void follow(int followerId, int followeeId) {// 被關(guān)注人不能是自己if (followeeId == followerId) {return;}// 獲取我自己的關(guān)注列表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;}followingList.add(followeeId);}}/*** Follower unfollows a followee. If the operation is invalid, it should be a no-op.** @param followerId 發(fā)起取消關(guān)注的人的 id* @param followeeId 被取消關(guān)注的人的 id*/public void unfollow(int followerId, int followeeId) {if (followeeId == followerId) {return;}// 獲取我自己的關(guān)注列表Set<Integer> followingList = followings.get(followerId);if (followingList == null) {return;}// 這里刪除之前無(wú)需做判斷,因?yàn)椴檎沂欠翊嬖谝院?#xff0c;就可以刪除,反正刪除之前都要查找followingList.remove(followeeId);}/*** 推文類,是一個(gè)單鏈表(結(jié)點(diǎn)視角)*/private class Tweet {/*** 推文 id*/private int id;/*** 發(fā)推文的時(shí)間戳*/private int timestamp;private Tweet next;public Tweet(int id, int timestamp) {this.id = id;this.timestamp = timestamp;}}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);}作者:liweiwei1419
鏈接:https://leetcode-cn.com/problems/design-twitter/solution/ha-xi-biao-lian-biao-you-xian-dui-lie-java-by-liwe/