[Leedcode][JAVA][第355题][设计推特][面向对象][哈希表][链表][优先队列]

【问题描述】355 设计推特

设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近十条推文。你的设计需要支持以下的几个功能:postTweet(userId, tweetId): 创建一条新的推文
getNewsFeed(userId): 检索最近的十条推文。每个推文都必须是由此用户关注的人或者是用户自己发出的。推文必须按照时间顺序由最近的开始排序。
follow(followerId, followeeId): 关注一个用户
unfollow(followerId, followeeId): 取消关注一个用户
示例:Twitter twitter = new Twitter();// 用户1发送了一条新推文 (用户id = 1, 推文id = 5).
twitter.postTweet(1, 5);// 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文.
twitter.getNewsFeed(1);
// 用户1关注了用户2.
twitter.follow(1, 2);
// 用户2发送了一个新推文 (推文id = 6).
twitter.postTweet(2, 6);
// 用户1的获取推文应当返回一个列表,其中包含两个推文,id分别为 -> [6, 5].
// 推文id6应当在推文id5之前,因为它是在5之后发送的.
twitter.getNewsFeed(1);
// 用户1取消关注了用户2.
twitter.unfollow(1, 2);
// 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文.
// 因为用户1已经不再关注用户2.
twitter.getNewsFeed(1);

【解答思路】

1. 设计思路

image.png
image.png

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 和推文(单链表)的对应关系*/private Map<Integer, Tweet> twitter;/*** 用户 id 和他关注的用户列表的对应关系*/private Map<Integer, Set<Integer>> followings;/*** 全局使用的时间戳字段,用户每发布一条推文之前 + 1*/private static int timestamp = 0;/*** 合并 k 组推文使用的数据结构(可以在方法里创建使用),声明成全局变量非必需,视个人情况使用*/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();// 如果自己发了推文也要算上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);// 这里最好的操作应该是 replace,但是 Java 没有提供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 发起关注者 id* @param followeeId 被关注者 id*/public void follow(int followerId, int followeeId) {// 被关注人不能是自己if (followeeId == followerId) {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;}followingList.add(followeeId);}}/*** Follower unfollows a followee. If the operation is invalid, it should be a no-op.** @param followerId 发起取消关注的人的 id* @param followeeId 被取消关注的人的 id*/public void unfollow(int followerId, int followeeId) {if (followeeId == followerId) {return;}// 获取我自己的关注列表Set<Integer> followingList = followings.get(followerId);if (followingList == null) {return;}// 这里删除之前无需做判断,因为查找是否存在以后,就可以删除,反正删除之前都要查找followingList.remove(followeeId);}/*** 推文类,是一个单链表(结点视角)*/private class Tweet {/*** 推文 id*/private int id;/*** 发推文的时间戳*/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/

【总结】

1.维护数据
  • 如果需要维护数据的时间有序性,链表在特殊场景下可以胜任。因为时间属性通常来说是相对固定的,而不必去维护顺序性;
  • 如果需要动态维护数据有序性,「优先队列」(堆)是可以胜任的;
2. maxHeap = new PriorityQueue<>((o1, o2) -> -o1.timestamp + o2.timestamp); 中的(o1, o2) -> -o1.timestamp + o2.timestamp
这里是 Java 的 lambda 表达式,等价于:Java 代码:maxHeap = new PriorityQueue<>(new Comparator<Tweet>() {@Overridepublic int compare(Tweet o1, Tweet o2) {return -o1.timestamp + o2.timestamp;}
});
lambda 表达式,它是把函数作为一个方法的参数的一种等价写法,可以认为是「语法糖」。在 IDEA 工具里面写匿名方法,然后再让 IDEA 帮助优化成 lambda 表达式。
3. 面向对象 注意细节 分级思考 想好再码

原文链接;https://leetcode-cn.com/problems/design-twitter/solution/ha-xi-biao-lian-biao-you-xian-dui-lie-java-by-liwe/

done is better than perfect

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习(157):线程的引入

//线程 public class test102 extends Thread{public void run(){while (true){System.out.println("我是线程1"this.getName());try {Thread.sleep( 1000 );}catch (InterruptedException e){e.printStackTrace();}}} }//线程 public class test103 extends Thread{…

【读书笔记】计算机是怎样跑起来的

2018年底读的&#xff0c;才整理完笔记。说说感想吧&#xff0c;每个章节虽然都是基础的知识&#xff0c;但是每次读起来还是收获颇多&#xff0c;很多自己说不清楚或者不理解的概念&#xff0c;感觉在认识层面有些结成网了。对于每个方面的专业知识&#xff0c;要按需深入学习…

[剑指offer][JAVA]面试题[第23题][合并K个排序链表][分治][优先队列]

【问题描述】23.合并K个排序链表 合并 k 个排序链表&#xff0c;返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [1->4->5,1->3->4,2->6 ] 输出: 1->1->2->3->4->4->5->6【解答思路】 1. 两两合并 public class Soluti…

[Leedcode][JAVA][第542题][01矩阵][BFS]

【问题描述】542. 01 矩阵 给定一个由 0 和 1 组成的矩阵&#xff0c;找出每个元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例 : 输入: 0 0 0 0 1 0 1 1 1 输出: 0 0 0 0 1 0 1 2 1 注意: 给定矩阵的元素个数不超过 10000。 给定矩阵中至少有一个元素是 0。 矩阵…

java学习(159):两个线程共同完成1到100计算

//利用两个线程实现1到100的计算 public class MyRannable implements java.lang.Runnable{private Thread th_0;private Thread th_2;int sum0;//存储累加和的结果int i1;public void run(){String thNameThread.currentThread().getName();//获取当前线程的名字while (i<…

java学习(160):interrupt方法

import java.util.PrimitiveIterator;public class Classroon implements Runnable {private Thread student;//学生线程private Thread teacher;//老师线程public Classroon(){student new Thread( this,"小迷糊" );teacher new Thread( this,"大教授" …

elementui图片上传php,vue+element-ui+富文本————图片上传

最近用vueelement-ui开发一套后台管理系统&#xff0c;其中项目中需要用到富文本编辑器&#xff0c;这里总结下开发过程中遇到的坑和使用方法。刚开始用的是vue-quill-editor结合element-ui上传图片到服务器&#xff0c;name问题来了 按照官方文档上面的方式。下面是我的代码cl…

[剑指offer][JAVA][面试第40题][最小的k个数][快选][堆][BST]

【问题描述】面试第40题 最小的k个数 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2、3、4。 示例 &#xff1a; 输入&#xff1a;arr [3,2,1], k 2 输出&#xff1a;[1,2] …

java学习(161):同步代码块

public class SynCode implements Runnable{public void run(){synchronized (this){Thread currentThread.currentThread();//获取当前线程for(int i1;i<10;i){System.out.println( "当前执行代码块的名称为" current.getName());try {Thread.sleep( 1000 );}cat…

[如何做研究][如何写论文]

音频 沈向洋&#xff1a;有效的科研法则 科学上网&#xff1a;https://www.youtube.com/watch?vU6r3R87AKHI&featureyoutu.be 视频 文章 【经典重温】MIT人工智能实验室: 如何做研究&#xff1f; 机器学习研究者的养成指南&#xff0c;吴恩达建议这么读论文 周志华 […

java学习(162):同步对象锁

定义一个dog类 public class Dog {private String name;public String getName() {return name;}public void setName(String name) {this.name name;} }定义一个同步对象锁 //同步对象锁 public class SysObject implements Runnable {private Dog dog;public SysObject(){…

[Leedcode][JAVA][第56题][合并区间][数组][贪心算法]

【问题描述】56.合并区间 给出一个区间的集合&#xff0c;请合并所有重叠的区间。 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].【解答思路】 1. 双指针 左边位置一定是确定&#xff0c;…

java读写注册表的两种方式,Preferences与jRegistry

打开注册表方式&#xff1a;电脑上的windows键加r键打开运行程序->输入指令regedit->随即系统便会提示你是否要运行&#xff0c;选择“是“就行了 由于java程序是“write once, run everywhere”&#xff0c;用java读写注册表&#xff0c;那程序的跨平台性就差了。java对…

java学习(163):同步方法锁

public class SynMethon implements Runnable{private double money1000000;public void run(){dbMoney();}//同步方法private synchronized void dbMoney(){Thread tThread.currentThread();for(int i1;i<10;i){if(t.getName().equals( "会计" )){moneyi*10;Sy…

PBFT

摘要&#xff1a; PBFT是Practical Byzantine Fault Tolerance的缩写&#xff0c;即&#xff1a;实用拜占庭容错算法。该算法是Miguel Castro&#xff08;卡斯特罗&#xff09;和Barbara Liskov&#xff08;利斯科夫&#xff09;在1999年提出来的&#xff0c;解决了原始拜占庭…

Python爬虫爬取美剧网站

一直有爱看美剧的习惯&#xff0c;一方面锻炼一下英语听力&#xff0c;一方面打发一下时间。之前是能在视频网站上面在线看的&#xff0c;可是自从广电总局的限制令之后&#xff0c;进口的美剧英剧等貌似就不在像以前一样同步更新了。 但是&#xff0c;作为一个宅diao的我又怎甘…

php 存储html 内容,HTML 本地存储

HTML 本地存储HTML 本地存储&#xff1a;优于 cookies。什么是 HTML 本地存储&#xff1f; ( 推荐学习&#xff1a;html教程 )通过本地存储(Local Storage)&#xff0c;web 应用程序能够在用户浏览器中对数据进行本地的存储。在 HTML5 之前&#xff0c;应用程序数据只能存储在 …

java学习(165):inetaddress和inetsocketaddress

import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException;//inetaddress public class test112 {public static void main(String[] args){try {InetAddress add0 InetAddress.getLocalHost();//获取本机ip地址实例System.out…

java学习(166):socket服务端和客户端连接

socket服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;//socket服务端 public class test114 {public static void main(String[] args){ServerSocket serverSocketnull;Socket clientnull;/*创建服务器套接字*/try {serverSocket…

[Leedcode][JAVA][第11题][盛最多水的容器][双指针][贪心]

【问题描述】11.盛最多水的容器 给你 n 个非负整数 a1&#xff0c;a2&#xff0c;...&#xff0c;an&#xff0c;每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线&#xff0c;垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线&#xff0c;使得它们与…