[路飞]_力扣算法题_355.设计推特

202 阅读3分钟

355.设计推特

难度 中等\color{#2db55d}{中等}

题目内容 设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近 10 条推文。 。

实现 Twitter 类:

Twitter() 初始化简易版推特对象 void postTweet(int userId, int tweetId) 根据给定的 tweetId 和 userId 创建一条新推文。每次调用此函数都会使用一个不同的 tweetId 。 List getNewsFeed(int userId) 检索当前用户新闻推送中最近  10 条推文的 ID 。新闻推送中的每一项都必须是由用户关注的人或者是用户自己发布的推文。推文必须 按照时间顺序由最近到最远排序 。 void follow(int followerId, int followeeId) ID 为 followerId 的用户开始关注 ID 为 followeeId 的用户。 void unfollow(int followerId, int followeeId) ID 为 followerId 的用户不再关注 ID 为 followeeId 的用户。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/de… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

image.png

image.png

image.png

  • 初始化对象,它保存两个数组,一个储存推文(tweets),一个储存用户(users)
var Twitter = function() {
    this.tweets = [];
    this.users = [];
};
  • 它需要实现如下方法

1.postTweet:接收用户和推文id,创建新推文,并绑定到用户
Twitter.prototype.postTweet = function(userId, tweetId){}

2.getNewsFeed:接收参数userId,查询id为userId的 $\color{red}{自己的和用户关注的}推文中,创建时间最新的10条
Twitter.prototype.getNewsFeed = function(userId) {}

3.follow:接收2个参数:发起关注的用户id(followerId)和被关注的用户id(followeeId)
3.1 followerId用户对followeeId用户发起关注
Twitter.prototype.follow = function(followerId, followeeId){}
3.2 followerId用户取消对followeeId用户的关注
Twitter.prototype.unfollow = function(followerId, followeeId)

于是我们需要设计2个类,User类和Tweet类:

// User类,接收一个id
class User {
    constructor(id) {
        this.id = id
        this.tweets = []    // 保存用户自己的tweet
        this.follows = []   // 此用户关注的人,保存user对象
    }
    // 以下是处理用户推文的API,全部都需要传入对象
    // 用户发布推文 param {tweet}: object Tweet
    addTweet(tweet) {
        this.tweets.push(tweet)
    }
    // news()方法,查询最新的用户自己的或用户关注人的推文10条
    news() {
        // 1.把此用户关注的用户的推文查询出来,这里使用Array.reduce方法转化
        const followTweets = this.follows.reduce((res, item) => res.concat(item.tweets), [])
        // 2.把此用户关注者的推文和自己的推文进行合并
        const resArr = this.tweets.concat(followTweets)
        // 3.根据创建时间把推文进行一次排序
        resArr.sort((a, b) => b.createdAt - a.createdAt)  // 从新到旧排序
        // 4.只取前10个,也就是最新的10条,并把推文对象数组转化为推文id数组返回出去
        return resArr.slice(0, 10).map(tweet => tweet.id)
    }
    // 用户关注了一位用户 param {user}: object User
    addFollow(user) {
        // 注意已被关注的用户不必再次关注
        if(this.follows.find(item => item===user)!==undefined) return 
        this.follows.push(user)
    }
    // 用户取消关注了一位用户 param {user}: object User
    unFollow(user) {
        // 把用户从follows中取消
        const index = this.follows.indexOf(user)
        // 排除不存在的情况
        if(index===-1) return
        this.follows.splice(index, 1)
    }
}
// Tweet类
class Tweet {
    constructor(id, user) {
        this.id = id
        // this.createdAt = Date.getTime();
        this.user = user;
        this.createdAt = Date.getTime();
        // 把自己插入user的队列中
        user.addTweet(this)
    }
}

有了上面2个类作为支持,可以编写Tweet类的几个方法了:

    /** 
 * @param {number} userId 
 * @param {number} tweetId
 * @return {void}
 */
Twitter.prototype.postTweet = function(userId, tweetId) {
    let user = this.users.find(user => user.id===userId);
    if(user===undefined) {
        user = new User(userId)
        this.users.push(user);
    }  
    // 创建新推文并传入user对象,tweet构造方法将把自己推入user.tweets中
    const tweet = new Tweet(tweetId, user)
    // 推入推文队列
    this.tweets.push(tweet)
};

/** 
 * @param {number} userId
 * @return {number[]}
 */
Twitter.prototype.getNewsFeed = function(userId) {
    // 找到用户
    const user = this.users.find(user => user.id===userId);
    if(user===undefined) return []
    // 返回新闻
    return user.news()
};

/** 
 * @param {number} followerId 
 * @param {number} followeeId
 * @return {void}
 */
Twitter.prototype.follow = function(followerId, followeeId) {
    // 查找两个用户对象
    let follower = this.users.find(user => user.id===followerId)
    let followee = this.users.find(user => user.id===followeeId)
    // 如果它们不在用户队列里,把它们加入队列
    if(follower===undefined) {
        follower = new User(followerId)
        this.users.push(follower);
    }  
    if(followee===undefined) {
        followee = new User(followeeId)
        this.users.push(followee);
    }  
    follower.addFollow(followee)
};

/** 
 * @param {number} followerId 
 * @param {number} followeeId
 * @return {void}
 */
Twitter.prototype.unfollow = function(followerId, followeeId) {
    // 查找两个用户对象
    let follower = this.users.find(user => user.id===followerId)
    let followee = this.users.find(user => user.id===followeeId)
    // 如果它们不在用户队列里,把它们加入队列
    if(follower===undefined) {
        follower = new User(followerId)
        this.users.push(follower);
    }  
    if(followee===undefined) {
        followee = new User(followeeId)
        this.users.push(followee);
    }  
    follower.unFollow(followee)
};

完成