355. Design Twitter

2 hashMap(Map<Integer, List<Tweet>>, ) + list sort

T: O(mnlogmn)

S: O(mn)

class Twitter {

    class Tweet {
        int userId;
        int tweetId;
        int timestamp;
        Tweet(int userId,
              int tweetId,
              int timestamp) {
            
            this.userId = userId;
            this.tweetId = tweetId;
            this.timestamp = timestamp;
        }
    }
    Map<Integer, List<Tweet>> postMap;
    Map<Integer, Set<Integer>> followMap;
    int timestamp = 0;
    
    public Twitter() {
        postMap = new HashMap<>();
        followMap = new HashMap<>();
    }
    
    public void postTweet(int userId, int tweetId) {
        postMap.putIfAbsent(userId, new ArrayList<>());
        postMap.get(userId).add(new Tweet(userId, tweetId, timestamp++));
    }
    
    public List<Integer> getNewsFeed(int userId) {
        List<Tweet> all = new ArrayList<>();
        // PriorityQueue<Tweet> pq = new PriorityQueue<>((a, b) -> b.timestamp - a.timestamp);
        
        for (int targetId : followMap.getOrDefault(userId, new HashSet<>())) {
            for (Tweet tweet : postMap.getOrDefault(targetId, new ArrayList<>())) {
                // pq.offer(tweet);
                all.add(tweet);
            }
        }
        for (Tweet tweet : postMap.getOrDefault(userId, new ArrayList<>())) {
            // pq.offer(tweet);
            all.add(tweet);
        }
        Collections.sort(all, (a, b) -> b.timestamp - a.timestamp);
        List<Integer> result = new ArrayList<>();
        // int n = 0;
        // while (!pq.isEmpty() && n < 10) {
        //     result.add(pq.poll().tweetId);
        //     n++;
        // }
        int n = 0;
        while (n < 10 && n < all.size()) {
            result.add(all.get(n).tweetId);
            n++;
        }
        return result;
    }
    
    public void follow(int followerId, int followeeId) { // follower follow followee
        followMap.putIfAbsent(followerId, new HashSet<>());
        followMap.get(followerId).add(followeeId);
    }
    
    public void unfollow(int followerId, int followeeId) {
        Set<Integer> set = followMap.getOrDefault(followerId, new HashSet<>());
        if (set.contains(followeeId)) {
            set.remove(followeeId);
        }
    }
}

/**
 * Your Twitter object will be instantiated and called as such:
 * Twitter obj = new Twitter();
 * obj.postTweet(userId,tweetId);
 * List<Integer> param_2 = obj.getNewsFeed(userId);
 * obj.follow(followerId,followeeId);
 * obj.unfollow(followerId,followeeId);
 
1. use 2 hashMap 
Map<Integer, List<Tweet>> postMap;
use ArrayList save all tweets with timestamp, postTweet: O(1)

Map<Integer, Set<Integer>> followMap;
use set to save followee, in that way, unfollow is O(1)
follow is also O(1)

getNewsFeed()
use PQ, but needs to get all followee * tweets count
add all followee * tweets count: O(mn)
PQ: O(mnlogmn) 

add all tweets into PQ to only add top 10 recent tweets to result
no difference comparing with just "sort"  ...because I get all tweets here and add all into PQ

so actually this solution is using list, add all followee * tweets count, then sort
add all followee * tweets count: O(mn)
sort: O(mnlogmn)

 */

hashMap(Map<Integer, User>) + User has tweet linkedlist, + PQ

still use 2 map + pq, but stop earlier, this is faster

Runtime: 10 ms, faster than 97.95% of Java online submissions

pq change to use minHeap, 當遇到 timestmap 比 heap peek 大的, 就把那個小的丟掉, 放入大的

這樣可以提早結束

最後用 linkedlist addFirst 的技巧, 達到大的在前面的效果(因為 minHeap 事先排出來最小的..

Last updated

Was this helpful?