New Users Daily Count
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.
logins = [(3,"06-25"), (1,"06-20"), (3,"06-22"), (2,"06-22"), (1,"06-25")]{ "06-20": 1, "06-22": 2 }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;
}
Explanation
A user should be counted as "new" on the day of their very first login, never again. So the real task is two simple steps: find each user's earliest date, then count how many users share each earliest date.
The first pass fills a hash map first where first[user] holds the smallest date seen for that user. For each login row we update it only when the new date is earlier (date < first[user]) or the user is brand new.
The second pass walks the values of first — one earliest date per user — and tallies them into a counts map of date → number of new users.
Example: logins (3,06-25), (1,06-20), (3,06-22), (2,06-22), (1,06-25). Earliest per user: user 1 → 06-20, user 2 → 06-22, user 3 → 06-22. Tallying gives {06-20: 1, 06-22: 2}.
The later logins (user 3 on 06-25, user 1 on 06-25) are not earlier than what we already stored, so they are ignored and never inflate any day's count.