|
| 1 | +# [Problem 2092: Find All People With Secret](https://leetcode.com/problems/find-all-people-with-secret/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +We need to simulate secret spread across meetings, but meetings can happen at same time and the secret spreads instantaneously across connected meetings at that same time. That suggests grouping meetings by time and processing time-by-time. Within a single time, multiple meetings form a graph (or connected components): if any node in a component already knows the secret at that time, the secret spreads to the whole component instantly. So for each time, build the connectivity among participants, determine which components contain a knower, and mark all nodes in those components as knowing the secret. Sorting meetings by time or grouping by time is necessary. Union-Find or BFS/DFS on the per-time graph both work. |
| 5 | + |
| 6 | +## Refining the problem, round 2 thoughts |
| 7 | +Refinements: |
| 8 | +- Maintain a global set "know" initially containing 0 and firstPerson (0 shares to firstPerson at time 0). |
| 9 | +- Sort meetings by time or bucket them; then process each time's meetings together. |
| 10 | +- For the meetings at a single time t: create a subgraph among participants of those meetings. Use union-find (fast) to group components, or adjacency list + BFS from known nodes in that time. Using union-find is concise: union every pair in the time group, then check which roots contain any knower. |
| 11 | +- After processing a time, only nodes that become known remain known for later times (do not carry forward edges). |
| 12 | +- Time complexity: sorting meetings O(m log m), processing unions/finds O(m α(n)). Space O(n + m) for grouping. |
| 13 | +- Edge cases: If none of the participants in a time group know the secret at that time, nobody in that group becomes known. Multiple meetings can involve same person; union-find handles that. |
| 14 | + |
| 15 | +## Attempted solution(s) |
| 16 | +```python |
| 17 | +from collections import defaultdict |
| 18 | + |
| 19 | +class Solution: |
| 20 | + def findAllPeople(self, n: int, meetings: list[list[int]], firstPerson: int) -> list[int]: |
| 21 | + # Group meetings by time |
| 22 | + time_map = defaultdict(list) |
| 23 | + for x, y, t in meetings: |
| 24 | + time_map[t].append((x, y)) |
| 25 | + # Process times in increasing order |
| 26 | + times = sorted(time_map.keys()) |
| 27 | + # Initially, person 0 and firstPerson know the secret |
| 28 | + know = {0, firstPerson} |
| 29 | + |
| 30 | + for t in times: |
| 31 | + pairs = time_map[t] |
| 32 | + # collect all participants in this time |
| 33 | + participants = set() |
| 34 | + for x, y in pairs: |
| 35 | + participants.add(x) |
| 36 | + participants.add(y) |
| 37 | + # build union-find for participants only |
| 38 | + parent = {p: p for p in participants} |
| 39 | + rank = {p: 0 for p in participants} |
| 40 | + |
| 41 | + def find(a): |
| 42 | + # path compression |
| 43 | + while parent[a] != a: |
| 44 | + parent[a] = parent[parent[a]] |
| 45 | + a = parent[a] |
| 46 | + return a |
| 47 | + |
| 48 | + def union(a, b): |
| 49 | + ra, rb = find(a), find(b) |
| 50 | + if ra == rb: |
| 51 | + return |
| 52 | + if rank[ra] < rank[rb]: |
| 53 | + parent[ra] = rb |
| 54 | + else: |
| 55 | + parent[rb] = ra |
| 56 | + if rank[ra] == rank[rb]: |
| 57 | + rank[ra] += 1 |
| 58 | + |
| 59 | + for x, y in pairs: |
| 60 | + union(x, y) |
| 61 | + |
| 62 | + # Determine which components have at least one knower |
| 63 | + roots_with_secret = set() |
| 64 | + for p in participants: |
| 65 | + if p in know: |
| 66 | + roots_with_secret.add(find(p)) |
| 67 | + |
| 68 | + # Those in components whose root is in roots_with_secret get the secret |
| 69 | + newly_known = set() |
| 70 | + if roots_with_secret: |
| 71 | + for p in participants: |
| 72 | + if find(p) in roots_with_secret: |
| 73 | + newly_known.add(p) |
| 74 | + |
| 75 | + # update global known set |
| 76 | + know |= newly_known |
| 77 | + |
| 78 | + return list(know) |
| 79 | +``` |
| 80 | +- Approach notes: We group meetings by time and process each time separately. For each time group we perform unions among participants to form connected components. If any participant in a component already knows the secret before processing this time, everyone in that component learns it immediately. We then update the global known set and proceed to the next time. |
| 81 | +- Complexity: |
| 82 | + - Let m = number of meetings, n = number of people. |
| 83 | + - Time: O(m log m) for sorting times + O(m α(n)) for union/find across all meetings (α is inverse-Ackermann, effectively constant). |
| 84 | + - Space: O(n + m) for grouping and per-time structures (parents/ranks only for participants of that time). |
0 commit comments