设计推特(Leetcode355)

例题:

https://leetcode.cn/problems/design-twitter/

分析:

推特其实类似于微博,在微博中可以发送文章。

求解这类题目,我们需要根据题目需求,利用面向对象的思想,先对需求做一个抽象,看看能抽象出哪些对象。可以看出,题目中有3个对象:推特对象、用户对象、文章对象。

下图表示这3类对象之间的关系:

我们知道,一个推特包含多个用户,推特和用户之间是一对多的关系,因此在推特类中可以创建一个map集合来保存用户数据;同样,一个用户可以发送多条文章,用户和文章也是一对多的关系,因为题目有一个方法,获取一个用户发送的近10条文章(其中包括关注者发送的),我们可以用一个链表来存储推文,在用户类中设置一个头节点。

一个用户也可以关注多个用户,用户与用户之间也是一对多的关系,可以用一个set集合存储关注的用户。

这里面有个方法getNewsFeed()获取最新的10篇文章, 包括自己发送的和关注者发送的,其实这就是一个多链表合并问题,按推文时间合并,可以采用大顶堆的方式把自己的推文和关注者的推文加入堆中,然后从堆中弹出一个最近的文章,然后再加入该链表的下一篇推文。

​​​​​ ​

如上图,假设①号链表 表示用户的推文,其它链表是关注者的推文,首先依次把 各链表的头节点加入堆中(10, 9, 3),在堆中弹出一篇最近的文章(10)。紧接着加入被弹出链表的下一个节点(6),再和其它链表头的元素相比选出最近的,依次类推。

代码实现:
java 复制代码
package leetcodeup;

import java.util.*;

public class TwitterLeetcode355 {

    static class Twitter {

        public Twitter() {

        }

        static class Tweet{
            int tweetId;
            int time;
            Tweet next;

            public Tweet(int tweetId, int time, Tweet next) {
                this.tweetId = tweetId;
                this.time = time;
                this.next = next;
            }

            public int getTweetId() {
                return tweetId;
            }

            public int getTime() {
                return time;
            }
        }

        static class User{
            int userId;

            public User(int userId) {
                this.userId = userId;
            }

            Tweet head = new Tweet(-1, -1, null);
            Set<Integer> followees = new HashSet<>();
        }

        private final Map<Integer, User> userMap = new HashMap<>();
        private static int time;
        //发布文章
        public void postTweet(int userId, int tweetId) {
            User user = userMap.computeIfAbsent(userId, User::new);
            user.head.next = new Tweet(tweetId, time++, user.head.next);
        }

        //新增关注
        public void follow(int followerId, int followeeId) {
            User user = userMap.computeIfAbsent(followerId, User::new);
            User followee = userMap.computeIfAbsent(followeeId, User::new);
            user.followees.add(followee.userId);
        }

        //取消关注
        public void unfollow(int followerId, int followeeId) {
            User user = userMap.get(followerId);
            if(user != null){
                user.followees.remove(followeeId);
            }
        }

        //获取最新的10篇文章(包括自己和关注者)
        public List<Integer> getNewsFeed(int userId) {
            PriorityQueue<Tweet> queue = new PriorityQueue<>(Comparator.comparingInt(Tweet::getTime).reversed());
            User user = userMap.get(userId);
            if(user == null){
                return List.of();
            }
            if(user.head.next != null){
                queue.offer(user.head.next);
            }
            Set<Integer> followees = user.followees;
            for (Integer id : followees) {
                User followee = userMap.get(id);
                if(followee.head.next != null){
                    queue.offer(followee.head.next);
                }
            }
            List<Integer> res = new ArrayList<>();
            int count = 0;
            while(!queue.isEmpty() && count < 10){
                Tweet tweet = queue.poll();
                res.add(tweet.tweetId);
                if(tweet.next != null){
                    queue.offer(tweet.next);
                }
                count++;
            }
            return res;
        }
    }
}
相关推荐
测开小菜鸟28 分钟前
使用python向钉钉群聊发送消息
java·python·钉钉
好奇龙猫1 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
P.H. Infinity1 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天1 小时前
java的threadlocal为何内存泄漏
java
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
caridle2 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^2 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋32 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花2 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
香菜大丸2 小时前
链表的归并排序
数据结构·算法·链表