New Users Daily Count

medium hash map grouping aggregation

Problem

A Traffic log holds rows of (user_id, activity, activity_date). For each date within a recent window, report how many users had their first ever login on that date. A user is counted only once — on the day of their earliest login activity. Below we model each login row as a pair user→date and find, per day, the number of users whose minimum login date equals that day.

Inputlogins = [(3,"06-25"), (1,"06-20"), (3,"06-22"), (2,"06-22"), (1,"06-25")]
Output{ "06-20": 1, "06-22": 2 }
User 1 first logged in on 06-20, users 2 and 3 first logged in on 06-22. The later logins (3 on 06-25, 1 on 06-25) do not add new users.

def new_users_daily_count(logins):
    first = {}
    for user, date in logins:
        if user not in first or date < first[user]:
            first[user] = date
    counts = {}
    for date in first.values():
        counts[date] = counts.get(date, 0) + 1
    return counts
function newUsersDailyCount(logins) {
  const first = new Map();
  for (const [user, date] of logins) {
    if (!first.has(user) || date < first.get(user)) {
      first.set(user, date);
    }
  }
  const counts = new Map();
  for (const date of first.values()) {
    counts.set(date, (counts.get(date) || 0) + 1);
  }
  return counts;
}
class Solution {
    public Map<String, Integer> newUsersDailyCount(String[][] logins) {
        Map<String, String> first = new HashMap<>();
        for (String[] row : logins) {
            String user = row[0], date = row[1];
            if (!first.containsKey(user) || date.compareTo(first.get(user)) < 0) {
                first.put(user, date);
            }
        }
        Map<String, Integer> counts = new HashMap<>();
        for (String date : first.values()) {
            counts.merge(date, 1, Integer::sum);
        }
        return counts;
    }
}
map<string, int> newUsersDailyCount(vector<pair<int, string>>& logins) {
    unordered_map<int, string> first;
    for (auto& row : logins) {
        int user = row.first; string date = row.second;
        if (!first.count(user) || date < first[user]) {
            first[user] = date;
        }
    }
    map<string, int> counts;
    for (auto& kv : first) counts[kv.second]++;
    return counts;
}
Time: O(n) Space: O(u)