355. Design Twitter

    
        /*
         * 355. Design Twitter
         * 2016-7-13 by Mingyang
         * 系统设计真的被玩坏了
         */
        class Twitter {
            private static int timeStamp=0;        
            // easy to find if user exist
            private Map<Integer, User> userMap;        
            // Tweet link to next Tweet so that we can save a lot of time
            // when we execute getNewsFeed(userId)
            private class Tweet{
                public int id;
                public int time;
                public Tweet next;            
                public Tweet(int id){
                    this.id = id;
                    time = timeStamp++;
                    next=null;
                }
            }        
            // OO design so User can follow, unfollow and post itself
            public class User{
                public int id;
                public Set<Integer> followed;
                public Tweet tweet_head;
                public User(int id){
                    this.id=id;
                    followed = new HashSet<>();
                    follow(id); // first follow itself
                    tweet_head = null;
                }
                public void follow(int id){
                    followed.add(id);
                }
                public void unfollow(int id){
                    followed.remove(id);
                }
                // everytime user post a new tweet, add it to the head of tweet list.
                public void post(int id){
                    Tweet t = new Tweet(id);
                    t.next=tweet_head;
                    tweet_head=t;
                }
            }
            /** Initialize your data structure here. */
            public Twitter() {
                userMap = new HashMap<Integer, User>();
            }            
            /** Compose a new tweet. */
            public void postTweet(int userId, int tweetId) {
                if(!userMap.containsKey(userId)){
                    User u = new User(userId);
                    userMap.put(userId, u);
                }
                userMap.get(userId).post(tweetId);                    
            }
            // Best part of this.
            // first get all tweets lists from one user including itself and all people it followed.
            // Second add all heads into a max heap. Every time we poll a tweet with 
            // largest time stamp from the heap, then we add its next tweet into the heap.
            // So after adding all heads we only need to add 9 tweets at most into this 
            // heap before we get the 10 most recent tweet.
            public List<Integer> getNewsFeed(int userId) {
                List<Integer> res = new LinkedList<>();
                if(!userMap.containsKey(userId))   return res;                
                Set<Integer> users = userMap.get(userId).followed;
                PriorityQueue<Tweet> q = new PriorityQueue<Tweet>(users.size(), new Comparator<Tweet>() {
                    @Override
                    public int compare(Tweet i1, Tweet i2) {
                        return i2.time - i1.time;
                    }
                });
                        //(a,b)->(b.time-a.time));
                for(int user: users){
                    Tweet t = userMap.get(user).tweet_head;
                    // very imporant! If we add null to the head we are screwed.
                    if(t!=null){
                        q.add(t);
                    }
                }
                int n=0;
                while(!q.isEmpty() && n<10){
                  Tweet t = q.poll();
                  res.add(t.id);
                  n++;
                  if(t.next!=null)
                    q.add(t.next);
                }            
                return res;
                
            }            
            /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
            public void follow(int followerId, int followeeId) {
                if(!userMap.containsKey(followerId)){
                    User u = new User(followerId);
                    userMap.put(followerId, u);
                }
                if(!userMap.containsKey(followeeId)){
                    User u = new User(followeeId);
                    userMap.put(followeeId, u);
                }
                userMap.get(followerId).follow(followeeId);
            }            
            /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
            public void unfollow(int followerId, int followeeId) {
                if(!userMap.containsKey(followerId) || followerId==followeeId)
                    return;
                userMap.get(followerId).unfollow(followeeId);
            }
        }
原文地址:https://www.cnblogs.com/zmyvszk/p/5669163.html