当前位置:网站首页>golang刷leetcode 经典(3) 设计推特
golang刷leetcode 经典(3) 设计推特
2022-08-02 17:37:00 【用户9710217】
设计一个简化版的推特(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);解题思路:
动态的实现一般使用“拉模式”或者“推模式”,即用户可以看到的动态可以采用查询的时候直接计算(拉)也可以在用户的关注者发推的时候直接“推”到用户的动态列表。 本文使用“推模式”实现,如下是用到的几个数据结构: a)tweets用来存放用户发表的推文; b)feeds用来存放每个用户可以看到的动态; c)fans用来存放用户的粉丝(关注者)列表。 接下来看一下几个方法的实现逻辑: PostTweet:当用户发送一条推文时,tweets存一下该推文的id与时间,feeds把该动态append到末尾; GetNewsFeed:从末尾开始遍历feeds,返回最近的10条推文id; Follow:有用户a关注用户b,则把a放入b的fans列表,且把b的tweets推文并入a的feeds,因合并的两部分均是按时间升序排列的数组,所以避免使用常规排序算法,使用自写的merge函数可以加速合并; Unfollow:用用户a取消关注b,则将a从b的fans列表移除,还要从a的feeds中移除b的tweets。
注意几个坑
1,用户follow自己不合法
2,重复follow,unfollow
3,按时间戳排序,最好是id生成器,这里用unixnano简化,1000qps足够了
type Twitter struct {
users map[int]*User
tweets map[int]*Tweet
}
type Tweet struct{
ID int
UID int
time int64
}
type User struct{
ID int
followers map[int]*User
followees map[int]*User //关注的人,推模式用,这里没有使用
feed []*Tweet
tweets []*Tweet
}
func NewUser(userId int)*User{
return &User{
ID:userId,
followers:make(map[int]*User),
followees:make(map[int]*User),
}
}
/** Initialize your data structure here. */
func Constructor() Twitter {
return Twitter{
users:make( map[int]*User),
tweets:make( map[int]*Tweet),
}
}
/** Compose a new tweet. */
func (this *Twitter) PostTweet(userId int, tweetId int) {
u,ok:=this.users[userId]
if !ok{
u=NewUser(userId)
this.users[userId]=u
}
t:=Tweet{ID:tweetId,UID:userId,time: time.Now().UnixNano()}
this.tweets[tweetId]=&t
//fmt.Println(*this,len(this.users[userId].followers))
//push
u.feed=append(u.feed,&t)
u.tweets=append(u.tweets,&t)
for _,f:=range u.followers{
//fmt.Println(f)
if f!=nil{
f.feed=append(f.feed,&t)
}
}
//fmt.Println(u)
}
/** 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. */
func (this *Twitter) GetNewsFeed(userId int) []int {
var r []int
u,ok:=this.users[userId]
if !ok{
return r
}
for i:=0;i<len(u.feed);i++{
if i==10 {
break
}
r=append(r,u.feed[len(u.feed)-1-i].ID)
}
return r
}
/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
func (this *Twitter) Follow(followerId int, followeeId int) {
if followerId==followeeId{
return
}
f1,ok:=this.users[followerId]
if !ok{
f1=NewUser(followerId)
//fmt.Println(1)
this.users[followerId]=f1
}
f2,ok:=this.users[followeeId]
if !ok{
f2=NewUser(followeeId)
// fmt.Println(2)
this.users[followeeId]=f2
}
if _,ok:=f2.followers[followerId];ok{
return
}
f2.followers[followerId]=f1
f1.feed=this.Merge(f1.feed,f2.tweets)
return
}
func (this *Twitter)Merge(f1,f2 []*Tweet)[]*Tweet{
if len(f1)==0{
return f2
}
if len(f2)==0{
return f1
}
var f []*Tweet
i:=0
j:=0
for i<len(f1) && j<len(f2){
if f1[i].time<f2[j].time{
f=append(f,f1[i])
i++
}else{
f=append(f,f2[j])
j++
}
}
for ;i<len(f1);i++{
f=append(f,f1[i])
}
for ;j<len(f2);j++{
f=append(f,f2[j])
}
return f
}
/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
func (this *Twitter) Unfollow(followerId int, followeeId int) {
if followerId==followeeId{
return
}
f1,ok:=this.users[followerId]
if !ok{
return
}
f2,ok:=this.users[followeeId]
if !ok{
return
}
if _,ok=f2.followers[followerId];!ok{
return
}
delete(f2.followers,followerId)
var feedNew []*Tweet
for i:=range f1.feed{
//fmt.Println(f1.feed[i].UID,f2.ID)
if f1.feed[i].UID!=f2.ID{
feedNew=append(feedNew,f1.feed[i])
}
}
f1.feed=feedNew
}
/**
* Your Twitter object will be instantiated and called as such:
* obj := Constructor();
* obj.PostTweet(userId,tweetId);
* param_2 := obj.GetNewsFeed(userId);
* obj.Follow(followerId,followeeId);
* obj.Unfollow(followerId,followeeId);
*/边栏推荐
- 暴跌99.7%后,谁还在买卖「二舅币」?
- Dream weaving prompt information prompt box beautification
- DeepMind 首席科学家 Oriol Vinyals 最新访谈:通用 AI 的未来是强交互式元学习
- 透过案例看清API接口的作用——演示1688商品详情接口
- redis summary_distributed cache
- Wechat Gymnasium Appointment Mini Program Graduation Design Finished Works Mini Program Graduation Design Finished Work (6) Question Opening Reply PPT
- LeetCode·每日一题·
- 莱斯大学胡侠团队 ICML 2022 杰出论文: 新型图数据增强方法 G-Mixup|附作者对话
- NeRF: The Secret of 3D Reconstruction Technology in the Popular Scientific Research Circle
- Flink学习9:配置idea开发flink-Scala程序环境
猜你喜欢

Gear 月度更新|6 月

How Tencent architects explained: The principle of Redis high-performance communication (essential version)

What is the difference between erp system and wms system

Smart Microelectronics Releases Low-Power MM32L0130 Series MCU Products

宝塔搭建实测-基于ThinkPHP5.1的wms进销存源码

用函数递归的方法解决汉诺塔问题

E-Surfing Cloud 4.0 Distributed Cloud Enables Digital Transformation of Thousands of Industries

Google Earth Engine APP—— 一个不用写代码可以直接下载相应区域的1984-2021年的GIF遥感影像动态图

AI+医疗:使用神经网络进行医学影像识别分析

攻防世界-favorite_number
随机推荐
租房小程序自动定位城市
LeetCode·76.最小覆盖子串·滑动窗口
golang源码阅读(11)GO中各个目录的功能
创新云集技术咖,工赋汇聚实战派:2022工赋开发者峰会
Flink Learning 9: Configure the idea to develop the flink-Scala program environment
莱斯大学胡侠团队 ICML 2022 杰出论文: 新型图数据增强方法 G-Mixup|附作者对话
Local broadcast MSE fragments mp4 service
ES: export 的用法
CUDA+Pycharm-gpu版本+Anaconda安装
谁抢走了华大基因的生意?
一篇文章带你搞定BFC~
Taking advantage of cloud-network integration, e-Surfing Cloud has paved the way for digital transformation for government and enterprises
HDF驱动框架的API(3)
Simulink脚本自动创建Autosar Parameter Port及Mapping
2021年下半年软件设计师上午真题
MySQL基本语法
基于HDF的LED驱动程序开发(1)
阿里云关系型数据库RDS是干嘛额?
Arduino hardware programming introduction to language learning
Remember the stuck analysis of an industrial automation control system in .NET