Count Mentions Per User

Medium
Watch on YouTube ↗

Solution

class Solution {
    public int[] countMentions(int n, List<List<String>> events) {
        
        int mentions[] = new int[n];

        // sorting events on the basis of timestamps
        // O(mlogm)
        Collections.sort(events, (a,b) -> {
            int t1 = Integer.parseInt(a.get(1));
            int t2 = Integer.parseInt(b.get(1));

            if(t1!=t2) {
                return Integer.compare(t1, t2);
            }

            // t1==t2
            if(a.get(0).equals("MESSAGE") && b.get(0).equals("OFFLINE")) {
                return 1;
            } else return -1;
        });

        // offline users
        int value = 0;
        HashMap<Integer, Integer> offline = new HashMap<>();
        // O(n*m)
        for(int i=0; i<events.size(); i++) {
            String type = events.get(i).get(0); // "MESSAGE" or "OFFLINE"
            int time = Integer.parseInt(events.get(i).get(1));

            if(type.equals("MESSAGE")) {
                // ALL, HERE, listofids
                String m_string = events.get(i).get(2);
                if(m_string.equals("ALL")) {
                    value++;
                } else if(m_string.equals("HERE")) {
                    increaseOnline(mentions, offline, time);
                } else {
                    String sids = events.get(i).get(2);
                    String ids[] = sids.split(" "); // id0, id1, id2
                    // O(n)
                    for(String id : ids) {
                        int intid = Integer.parseInt(id.substring(2));
                        mentions[intid]++;
                    }
                }
            }
            else {
                // offline 
                int id = Integer.parseInt(events.get(i).get(2));
                offline.put(id, time);
            }
        }
        increaseAll(mentions, value);

        return mentions;

    }

    void increaseAll(int arr[], int value) {
        for(int i=0; i<arr.length; i++) {
            arr[i]+=value;
        }
    }

    void increaseOnline(int arr[], HashMap<Integer, Integer> offline, int currtime) {

        for(int i=0; i<arr.length; i++) {
            if(offline.containsKey(i)) {
                int prevtime = offline.get(i);
                if(currtime - prevtime >=60) {
                    arr[i]++;
                    offline.remove(i);
                }
            }
            else {
                arr[i]++;
            }
        }

    }
}
/*

Input: numberOfUsers = 2, 
events = 
[["MESSAGE","10","id1 id0"],
["OFFLINE","11","0"],
["MESSAGE","71","HERE"]]
HERE -- online users = all-offline

mentions = [2,2]

offline = [0-11] 71th

Output: [2,2]

["OFFLINE","71","0"],
["MESSAGE","71","HERE"]]

1. Events array need to be sorted on the basis of timestamp
    If t1==t2
        then process offline event first
2.  Processing all the events
    mentions[]
*/