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 arrayanswer of size k such that, for each j (1 <= j <= k), answer[j] is the number of users whose UAM equals j.
Return the array answer as described above.
Input & Output
Example 1 — Basic Case
$Input:logs = [[0,5],[1,2],[0,2],[0,5],[1,3]], k = 5
›Output:[0,2,0,0,0]
💡 Note:User 0 has UAM=2 (minutes 2,5), User 1 has UAM=2 (minutes 2,3). So 0 users have UAM=1, 2 users have UAM=2, and 0 users have UAM=3,4,5.
Example 2 — Single User
$Input:logs = [[1,1],[1,2],[1,3]], k = 4
›Output:[0,0,1,0]
💡 Note:User 1 has UAM=3 (minutes 1,2,3). So 1 user has UAM=3, others are 0.
Example 3 — Duplicate Minutes
$Input:logs = [[0,1],[0,1],[1,1]], k = 3
›Output:[2,0,0]
💡 Note:User 0 has UAM=1 (minute 1 counted once), User 1 has UAM=1 (minute 1). So 2 users have UAM=1.
The key insight is to group logs by user ID first, then count unique minutes per user, and finally count users by UAM values. Best approach is Two-Pass Hash Map with Time: O(n), Space: O(n).
Common Approaches
✓
Union Find
⏱️ Time: N/A
Space: N/A
Brute Force with Nested Loops
⏱️ Time: O(n × u)
Space: O(u + k)
Find all unique users first. For each user, scan through all logs to collect their unique active minutes. Count how many users have each UAM value.
Two-Pass Hash Map
⏱️ Time: O(n + u)
Space: O(n + k)
Use a hash map to collect unique minutes for each user in one pass. Then iterate through the map to count how many users have each UAM value.
Algorithm Steps — Algorithm Steps
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct {
int* parent;
int* rank;
int size;
} UnionFind;
UnionFind* createUF(int size) {
UnionFind* uf = (UnionFind*)malloc(sizeof(UnionFind));
uf->parent = (int*)malloc(size * sizeof(int));
uf->rank = (int*)calloc(size, sizeof(int));
uf->size = size;
for (int i = 0; i < size; i++) {
uf->parent[i] = i;
}
return uf;
}
int find(UnionFind* uf, int x) {
if (uf->parent[x] != x) {
uf->parent[x] = find(uf, uf->parent[x]);
}
return uf->parent[x];
}
void unite(UnionFind* uf, int x, int y) {
int px = find(uf, x);
int py = find(uf, y);
if (px == py) return;
if (uf->rank[px] < uf->rank[py]) {
uf->parent[px] = py;
} else if (uf->rank[px] > uf->rank[py]) {
uf->parent[py] = px;
} else {
uf->parent[py] = px;
uf->rank[px]++;
}
}
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
bool solution(int* nums, int n) {
if (n <= 1) return true;
int* sortedNums = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
sortedNums[i] = nums[i];
}
qsort(sortedNums, n, sizeof(int), compare);
UnionFind* uf = createUF(n);
// Union positions that can be swapped (gcd > 1)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (gcd(nums[i], nums[j]) > 1) {
unite(uf, i, j);
}
}
}
// For each position i, check if the value at position i can reach
// the position where it should be in the sorted array
for (int i = 0; i < n; i++) {
int currentVal = nums[i];
bool found = false;
// Find a position in sorted array where currentVal should go
// and check if it's reachable from position i
for (int j = 0; j < n; j++) {
if (sortedNums[j] == currentVal) {
if (find(uf, i) == find(uf, j)) {
// Mark this target position as used
sortedNums[j] = -1; // Mark as used
found = true;
break;
}
}
}
if (!found) {
free(sortedNums);
free(uf->parent);
free(uf->rank);
free(uf);
return false;
}
}
free(sortedNums);
free(uf->parent);
free(uf->rank);
free(uf);
return true;
}
void parseArray(const char* str, int* arr, int* size) {
*size = 0;
const char* p = str;
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0') break;
arr[(*size)++] = (int)strtol(p, (char**)&p, 10);
}
}
int main() {
char line[10000];
fgets(line, sizeof(line), stdin);
if (strstr(line, "[]") != NULL) {
printf("true\n");
return 0;
}
int nums[1000];
int n = 0;
char* token = strtok(line, "[],\n");
while (token != NULL) {
if (strlen(token) > 0) {
nums[n++] = atoi(token);
}
token = strtok(NULL, "[],\n");
}
bool result = solution(nums, n);
printf(result ? "true\n" : "false\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
n
2n
✓ Linear Growth
Space Complexity
n
2n
⚡ Linearithmic Space
12.0K Views
MediumFrequency
~15 minAvg. Time
450 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.