355. Design Twitter , 用23. Merge k Sorted Lists和OOD思想解答。

大米中的大米
  1. Merge k Sorted Lists

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null) return null;
        // O(k) construct heap, m*logk do iterate,  Space O(k)
        // lamda expression is super slow 99ms vs 26ms Comparator
        // PriorityQueue<Tweet> pq = new PriorityQueue<Tweet>((a,b) -> (a.val-b.val));
        PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>(new Comparator<ListNode>(){
            @Override
            public int compare(ListNode l1, ListNode l2) {
                return l1.val - l2.val;
            }
        });
        
        for(ListNode l:lists) {
            if(l != null) pq.offer(l);
        }
        // every new list need a dummy node
        ListNode dummy = new ListNode(0);
        ListNode pre = dummy;
        while(!pq.isEmpty()){
            ListNode cur = pq.poll();
            pre.next = cur;
            if(cur.next != null) pq.offer(cur.next);
            pre = pre.next;
        }
        
        return dummy.next;
    }
}
Merge k Sorted Lists的想法就是用PriorityQueue每次得到最小的链表头的值,输出。如果next!=null,继续放到PriorityQueue里。
Twitter 本质上就是一个消息列表,按时间顺序从关注人列表里得到他们的tweets并整合显示。
每个user都有一个关注人列表,用hashset储存。还有一个tweets消息列表,这里按时间线就已经形成一个Sorted List.
一个user要得到最新的tweets, 首先找到关注人,把他们的tweets消息列表存到PriorityQueue里,就变成了Merge k Sorted Lists.
这里用OOD是因为更接近现实情况。twitter就是一个用户看到关注人消息集合的媒体。
基本的entity就是消息tweets和用户user。
tweets要体现出时间线,就要模拟linkedlist。
user用户可以发消息,关注别人,取消关注别人。
user可以twitter系统得到关注人的消息合集,这个方法必须在twitter这个层级。因为用户只知道自己的信息。
public class Twitter {
    private static int timestamp = 0;
    
    private Map<Integer, User> userMap;
    
    class Tweet{
        public int id;
        public int time;
        public Tweet next;
        
        public Tweet(int id) {
            this.id = id;
            time = timestamp++;
            next = null;
        }
    }
    
    public class User{
        public int id;
        public Set<Integer> followed;
        public Tweet tweet_head;
        
        public User(int id) {
            this.id = id;
            followed = new HashSet<Integer>();
            follow(id);
            tweet_head = null;
        }
        
        public void follow(int id) {
            followed.add(id);
        }
        
        public void unfollow(int id){
            followed.remove(id);
        }
        
        public void post(int id){
            Tweet tweet = new Tweet(id);
            tweet.next = tweet_head;
            tweet_head = tweet;
        }
    }
    
    
    
    /** 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);
    }
    
    /** 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) {
        List<Integer> news = new LinkedList<>();
        if(!userMap.containsKey(userId)){
            return news;
        }
        
        Set<Integer> users = userMap.get(userId).followed;
        PriorityQueue<Tweet> pq = new PriorityQueue<Tweet>(users.size(), (a,b) -> (b.time - a.time));
        for(int u:users){
            Tweet t = userMap.get(u).tweet_head;
            if(t != null)  {
                pq.offer(t);
            }
        }
        
        int n = 0;
        while(!pq.isEmpty() && n < 10) {
            Tweet t = pq.poll();
            news.add(t.id);
            if(t.next != null) {
                pq.offer(t.next);
            }
            n++;
        }
        
        return news;
    }
    
    /** 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);
    }
}

/**
 * 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);
 */
阅读 2k

你的code
记录日常刷leetcode的思路和总结。

你的code是面向面试编程的,收集和整理leetcode discussion里个人认为的最优且最符合我个人思维逻辑的解...

12 声望
4 粉丝
0 条评论

你的code是面向面试编程的,收集和整理leetcode discussion里个人认为的最优且最符合我个人思维逻辑的解...

12 声望
4 粉丝
文章目录
宣传栏