题目地址:
https://leetcode.com/problems/design-twitter/
设计推特,实现下列方法:
1、postTweet(userId, tweetId)
,某个userId可以发个推特,他发的内容简化为一个int整数;
2、getNewsFeed(userId)
,得到这个userId和所有他follow的人的总共
10
10
10条最近的推特内容,要按照发推特的次序返回,最新发的在前,旧的在后;
3、follow(followerId, followeeId)
,followerId这个人关注followeeId这个人;
4、unfollow(followerId, followeeId)
,followerId这个人取消关注followeeId这个人。
注意,如果follow或者unfollow的两个参数相同,则什么都不做。
参考https://blog.csdn.net/qq_46105170/article/details/112343519。代码如下:
import java.util.*;
public class Twitter {
class Account {
class ListNode {
int tweet, time;
ListNode prev, next;
public ListNode(int tweet, int time) {
this.tweet = tweet;
this.time = time;
}
}
private int size;
private ListNode head, tail;
public void post(int tweet) {
if (size == 0) {
head = tail = new ListNode(tweet, time++);
size++;
} else {
head.prev = new ListNode(tweet, time++);
head.prev.next = head;
head = head.prev;
size++;
// 如果这个人发了10条以上的推特了,则删掉最旧的那条
if (size > 10) {
tail = tail.prev;
tail.next = null;
}
}
}
public ListNode getHead() {
return head;
}
}
// 这个time记录时间戳,要设置为静态变量,任何人发了推特这个变量都会自增
private static int time;
private Map<Integer, Set<Integer>> followMap;
private Map<Integer, Account> accountMap;
/**
* Initialize your data structure here.
*/
public Twitter() {
followMap = new HashMap<>();
accountMap = new HashMap<>();
}
/**
* Compose a new tweet.
*/
public void postTweet(int userId, int tweetId) {
accountMap.putIfAbsent(userId, new Account());
accountMap.get(userId).post(tweetId);
}
/**
* 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) {
List<Integer> res = new ArrayList<>();
// 按ListNode时间戳大的优先,开一个最大堆
PriorityQueue<Account.ListNode> maxHeap = new PriorityQueue<>((t1, t2) -> -Integer.compare(t1.time, t2.time));
if (accountMap.containsKey(userId)) {
maxHeap.offer(accountMap.get(userId).getHead());
}
if (followMap.containsKey(userId)) {
for (int followee : followMap.get(userId)) {
if (accountMap.containsKey(followee)) {
maxHeap.offer(accountMap.get(followee).getHead());
}
}
}
while (res.size() < 10 && !maxHeap.isEmpty()) {
Account.ListNode cur = maxHeap.poll();
res.add(cur.tweet);
if (cur.next != null) {
maxHeap.offer(cur.next);
}
}
return res;
}
/**
* 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;
}
followMap.putIfAbsent(followerId, new HashSet<>());
followMap.get(followerId).add(followeeId);
}
/**
* Follower unfollows a followee. If the operation is invalid, it should be a no-op.
*/
public void unfollow(int followerId, int followeeId) {
if (followMap.containsKey(followerId)) {
followMap.get(followerId).remove(followeeId);
}
}
}
除了操作 2 2 2,所有操作时间复杂度 O ( 1 ) O(1) O(1),如果询问的人关注了 k k k个人,则操作 3 3 3复杂度 O ( k log k ) O(k\log k) O(klogk),空间复杂度是 O ( n ) O(n) O(n), n n n是拥有账号的总人数。