Count Distinct Active Pins per Time Segment from Overlapping Interaction Logs
Company: Pinterest
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Onsite
You are given interaction logs for pins. Each log `[pin_id, start, end]` means that some user was interacting with pin `pin_id` during the half-open time interval `[start, end)`. For every elementary time segment defined by the logs, report how many distinct pins were being interacted with.
The same pin can appear in many logs, because several users can interact with it, and its intervals can overlap. A pin counts once in a segment, no matter how many of its intervals cover that segment.
This is the last step of a three-step progression. The first version limited timestamps to a 60-second window (0 to 59) and assumed each pin appeared in at most one log. The second version removed the window limit, allowing arbitrary timestamps. This version also removes the one-log-per-pin assumption.
### Function Signature
```python
def distinct_active_pins(logs: list[list[int]]) -> list[list[int]]:
...
```
### Rules
- Let `T` be the sorted list of distinct values that appear as a `start` or an `end` in any log.
- For each pair of consecutive values `T[i] < T[i + 1]`, output one row `[T[i], T[i + 1], count]`. Here `count` is the number of distinct `pin_id` values that have at least one log with `start <= T[i]` and `T[i + 1] <= end`.
- Output the rows in ascending order of their start time. Output a row for every consecutive pair, including rows whose count is `0` and neighboring rows with equal counts. Do not merge rows.
- Intervals are half-open. A log that ends at time `t` and another that starts at time `t` do not overlap.
- If `logs` is empty, return an empty list.
### Constraints
- `0 <= len(logs) <= 100000`
- `0 <= pin_id <= 10^9`
- `0 <= start < end <= 10^12`
- Timestamps can exceed `2^31 - 1`, so use 64-bit integers.
- Logs are unsorted, and some may be exact duplicates of each other.
### Examples
Input: `logs = [[7, 1, 5], [7, 3, 8], [9, 4, 6]]`
Output: `[[1, 3, 1], [3, 4, 1], [4, 5, 2], [5, 6, 2], [6, 8, 1]]`
During `[3, 5)`, two of pin 7's logs overlap, but pin 7 is counted only once.
Input: `logs = [[1, 0, 2], [2, 5, 6]]`
Output: `[[0, 2, 1], [2, 5, 0], [5, 6, 1]]`
Overview: Given pin interaction logs with start and end times, count how many distinct pins are active in each time segment when the same pin can have many overlapping intervals from different users. Tests interval processing over arbitrary timestamps, deduplication by pin, and precise half-open boundary handling.
Read the full Pinterest Software Engineer interview experience this question came from
You are given interaction logs for pins. Each log is a triple `[pin_id, start, end]` meaning that some user interacted with pin `pin_id` during the half-open time interval `[start, end)`. The same pin can appear in many logs, because several users can interact with it, and its intervals can overlap or even be exact duplicates. A pin counts once in a segment, no matter how many of its intervals cover that segment.
For every elementary time segment defined by the logs, report how many distinct pins were being interacted with:
- Let `T` be the sorted list of the distinct values that appear as a `start` or an `end` in any log.
- For each pair of consecutive values `T[i] < T[i + 1]`, output one row `[T[i], T[i + 1], count]`, where `count` is the number of distinct `pin_id` values that have at least one log with `start <= T[i]` and `T[i + 1] <= end`.
- Output the rows in ascending order of their start time. Output a row for every consecutive pair, including rows whose count is `0` and neighbouring rows with equal counts. Do not merge rows.
- Intervals are half-open: a log that ends at time `t` and another that starts at time `t` do not overlap.
- If `logs` is empty, return an empty list.
Timestamps can exceed `2^31 - 1` (they go up to `10^12`), so use 64-bit integers: `long` in Java and `long long` in C++.
Example 1
Input: `logs = [[7, 1, 5], [7, 3, 8], [9, 4, 6]]`
Output: `[[1, 3, 1], [3, 4, 1], [4, 5, 2], [5, 6, 2], [6, 8, 1]]`
During `[3, 5)`, two of pin 7's logs overlap, but pin 7 is counted only once.
Example 2
Input: `logs = [[1, 0, 2], [2, 5, 6]]`
Output: `[[0, 2, 1], [2, 5, 0], [5, 6, 1]]`
The segment `[2, 5)` has no active pin, but its row is still emitted with count `0`.
Constraints
- 0 <= len(logs) <= 100000
- Each log is exactly [pin_id, start, end]
- 0 <= pin_id <= 10^9
- 0 <= start < end <= 10^12
- Timestamps can exceed 2^31 - 1, so use 64-bit integers (long in Java, long long in C++)
- Logs are unsorted, and some may be exact duplicates of each other
Examples
Input: ([],)
Expected Output: []
Explanation: Minimum valid input: no logs, so there are no boundary values and the result is empty.
Input: ([[3, 2, 5]],)
Expected Output: [[2, 5, 1]]
Explanation: Singleton: boundaries are [2, 5], and the single segment [2, 5) is covered by pin 3.
Hints
- Every row boundary is already present in the input: only values that appear as some start or some end can begin or end a segment, so the full set of candidate boundaries is fixed before you count anything.
- The intervals are half-open, so a timestamp t that ends one log and starts another belongs only to the segment beginning at t; settle what happens at t before you record the row that starts there.
- A pin may appear in several logs that overlap, so 'one of this pin's logs just ended' is not the same as 'this pin is no longer active'.