Problem

You are given the logs for users’ actions on LeetCode, and an integer k. The logs are represented by a 2D integer array logs where each logs[i] = [IDi, timei] indicates that the user with IDi performed an action at the minute timei.

Multiple users can perform actions simultaneously, and a single user can perform multiple actions in the same minute.

The user active minutes (UAM) for a given user is defined as the number of unique minutes in which the user performed an action on LeetCode. A minute can only be counted once, even if multiple actions occur during it.

You are to calculate a 1-indexed array answer of size k such that, for each j (1 <= j <= k), answer[j] is the number of users whose UAM equals j.

Return the arrayanswer as described above.

Examples

Example 1

1
2
3
4
5
6
Input: logs = [[0,5],[1,2],[0,2],[0,5],[1,3]], k = 5
Output: [0,2,0,0,0]
Explanation:
The user with ID=0 performed actions at minutes 5, 2, and 5 again. Hence, they have a UAM of 2 (minute 5 is only counted once).
The user with ID=1 performed actions at minutes 2 and 3. Hence, they have a UAM of 2.
Since both users have a UAM of 2, answer[2] is 2, and the remaining answer[j] values are 0.

Example 2

1
2
3
4
5
6
7
Input: logs = [[1,1],[2,2],[2,3]], k = 4
Output: [1,1,0,0]
Explanation:
The user with ID=1 performed a single action at minute 1. Hence, they have a UAM of 1.
The user with ID=2 performed actions at minutes 2 and 3. Hence, they have a UAM of 2.
There is one user with a UAM of 1 and one with a UAM of 2.
Hence, answer[1] = 1, answer[2] = 1, and the remaining values are 0.

Constraints

  • 1 <= logs.length <= 10^4
  • 0 <= IDi <= 10^9
  • 1 <= timei <= 10^5
  • k is in the range [The maximum **UAM** for a user, 105].

Solution

Method 1 – Hash Map and Counting

Intuition

We use a hash map to track the set of unique minutes for each user. Then, for each user, we count how many users have each possible UAM (user active minutes) value.

Approach

  1. For each log entry, add the minute to a set for the corresponding user ID.
  2. For each user, count the size of their set (their UAM).
  3. For each possible UAM value from 1 to k, count how many users have that UAM.
  4. Return the answer array.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    vector<int> findingUsersActiveMinutes(vector<vector<int>>& logs, int k) {
        unordered_map<int, unordered_set<int>> mp;
        for (auto& log : logs) mp[log[0]].insert(log[1]);
        vector<int> ans(k);
        for (auto& [id, st] : mp) {
            int uam = st.size();
            if (uam >= 1 && uam <= k) ans[uam-1]++;
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func findingUsersActiveMinutes(logs [][]int, k int) []int {
    mp := map[int]map[int]struct{}{}
    for _, log := range logs {
        if mp[log[0]] == nil {
            mp[log[0]] = map[int]struct{}{}
        }
        mp[log[0]][log[1]] = struct{}{}
    }
    ans := make([]int, k)
    for _, st := range mp {
        uam := len(st)
        if uam >= 1 && uam <= k {
            ans[uam-1]++
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int[] findingUsersActiveMinutes(int[][] logs, int k) {
        Map<Integer, Set<Integer>> mp = new HashMap<>();
        for (int[] log : logs) mp.computeIfAbsent(log[0], x -> new HashSet<>()).add(log[1]);
        int[] ans = new int[k];
        for (Set<Integer> st : mp.values()) {
            int uam = st.size();
            if (uam >= 1 && uam <= k) ans[uam-1]++;
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    fun findingUsersActiveMinutes(logs: Array<IntArray>, k: Int): IntArray {
        val mp = mutableMapOf<Int, MutableSet<Int>>()
        for (log in logs) mp.computeIfAbsent(log[0]) { mutableSetOf() }.add(log[1])
        val ans = IntArray(k)
        for (st in mp.values) {
            val uam = st.size
            if (uam in 1..k) ans[uam-1]++
        }
        return ans
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
    def findingUsersActiveMinutes(self, logs: list[list[int]], k: int) -> list[int]:
        from collections import defaultdict
        mp = defaultdict(set)
        for uid, t in logs:
            mp[uid].add(t)
        ans = [0] * k
        for st in mp.values():
            uam = len(st)
            if 1 <= uam <= k:
                ans[uam-1] += 1
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
impl Solution {
    pub fn finding_users_active_minutes(logs: Vec<Vec<i32>>, k: i32) -> Vec<i32> {
        use std::collections::{HashMap, HashSet};
        let mut mp: HashMap<i32, HashSet<i32>> = HashMap::new();
        for log in logs {
            mp.entry(log[0]).or_default().insert(log[1]);
        }
        let mut ans = vec![0; k as usize];
        for st in mp.values() {
            let uam = st.len();
            if uam >= 1 && uam <= k as usize {
                ans[uam-1] += 1;
            }
        }
        ans
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    findingUsersActiveMinutes(logs: number[][], k: number): number[] {
        const mp = new Map<number, Set<number>>();
        for (const [id, t] of logs) {
            if (!mp.has(id)) mp.set(id, new Set());
            mp.get(id)!.add(t);
        }
        const ans = Array(k).fill(0);
        for (const st of mp.values()) {
            const uam = st.size;
            if (uam >= 1 && uam <= k) ans[uam-1]++;
        }
        return ans;
    }
}

Complexity

  • ⏰ Time complexity: O(n), where n is the number of logs, since we process each log and user once.
  • 🧺 Space complexity: O(u), where u is the number of unique users.