Coding problem · Easy · Data Processing
Group Events into Sessions
Easy Practical tasks Seen at Amplitude, Spotify, Netflix
Analytics tools group a user's events into sessions: a new session starts whenever more than gapSeconds pass without activity.
Given event timestamps (seconds, unsorted, may contain duplicates) and gapSeconds, return the sessions as lists of timestamps, in chronological order. Two consecutive events belong to the same session when next - previous <= gapSeconds.
Example 1
Input: timestamps = [100, 30, 0, 1950, 2000], gapSeconds = 1800 Output: [[0,30,100],[1950,2000]]
Hints
Hint 1
Sort first; then a single pass decides 'same session or new one' by comparing with the previous timestamp.
Write and run your solution
Loading the editor… (JavaScript is required to run code in your browser.)
Solution and explanation
Show the solution
Time O(n log n) · Space O(n)
Sort the timestamps, start a session with the first one, and for each next timestamp either append it (gap ≤ threshold) or close the session and start a new one. Sorting dominates: O(n log n).
Reference solution
function sessionize(timestamps, gapSeconds) {
const sorted = [...timestamps].sort((a, b) => a - b);
const sessions = [];
for (const t of sorted) {
const current = sessions[sessions.length - 1];
if (current && t - current[current.length - 1] <= gapSeconds) current.push(t);
else sessions.push([t]);
}
return sessions;
}
function sessionize(timestamps: number[], gapSeconds: number): number[][] {
const sessions: number[][] = [];
for (const t of [...timestamps].sort((a, b) => a - b)) {
const current = sessions.at(-1);
if (current && t - current[current.length - 1] <= gapSeconds) current.push(t);
else sessions.push([t]);
}
return sessions;
}
def sessionize(timestamps: list[int], gap_seconds: int) -> list[list[int]]:
sessions: list[list[int]] = []
for t in sorted(timestamps):
if sessions and t - sessions[-1][-1] <= gap_seconds:
sessions[-1].append(t)
else:
sessions.append([t])
return sessions
<?php
function sessionize(array $timestamps, int $gapSeconds): array
{
sort($timestamps);
$sessions = [];
foreach ($timestamps as $t) {
$last = count($sessions) - 1;
if ($last >= 0 && $t - end($sessions[$last]) <= $gapSeconds) {
$sessions[$last][] = $t;
} else {
$sessions[] = [$t];
}
}
return $sessions;
}
class Solution {
public List<List<Integer>> sessionize(int[] timestamps, int gapSeconds) {
int[] sorted = timestamps.clone();
Arrays.sort(sorted);
List<List<Integer>> sessions = new ArrayList<>();
for (int t : sorted) {
List<Integer> current = sessions.isEmpty() ? null : sessions.get(sessions.size() - 1);
if (current != null && t - current.get(current.size() - 1) <= gapSeconds) current.add(t);
else sessions.add(new ArrayList<>(List.of(t)));
}
return sessions;
}
}
Common mistakes
- Forgetting to sort — events often arrive out of order.
- Off-by-one on the boundary (
<=vs<).
Follow-up questions
- Compute session duration and events per session.
- Sessionize a stream that never ends (emit when a gap timer fires).
More Data Processing problems
- Top Endpoints from Access Logs · Medium
- Flatten Nested JSON · Medium
- Revenue Report from CSV · Easy