Skip to content

Commit 9955fc2

Browse files
authored
feat: add solutions to lc problem: No.2092 (#4911)
1 parent 0a2deec commit 9955fc2

File tree

5 files changed

+206
-133
lines changed

5 files changed

+206
-133
lines changed

solution/2000-2099/2092.Find All People With Secret/README.md

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,21 @@ tags:
8989

9090
<!-- solution:start -->
9191

92-
### 方法一:BFS
92+
### 方法一:模拟 + 图遍历
93+
94+
本题的核心思路是通过模拟会议的传播过程来找出所有最终会知道秘密的人。我们可以将每次会议视为一个无向图的边,其中每个参与者是图中的一个节点,会议的时间是节点之间连接的边的“时间戳”。在每个时间点,我们遍历所有会议,利用广度优先搜索(BFS)来模拟秘密的传播。
95+
96+
创建一个布尔数组 $\textit{vis}$ 来记录每个人是否知道秘密。初始时,$\textit{vis}[0] = \text{true}$ 和 $\textit{vis}[\textit{firstPerson}] = \text{true}$,表示0号和 $\textit{firstPerson}$ 已经知道秘密。
97+
98+
我们首先按照每个会议的时间进行排序,以确保每次遍历时能够按照正确的顺序处理会议。
99+
100+
接下来,处理每一组相同时间的会议。对于每一组相同时间的会议(即 $\textit{meetings}[i][2] = \textit{meetings}[i+1][2]$),我们将它们视为同一时刻发生的事件。对于每个会议,记录参与者的关系,并将这些参与者加入一个集合中。
101+
102+
然后,我们利用 BFS 来传播秘密。对于当前时间点的所有参与者,如果其中有任何人已经知道秘密,我们将通过 BFS 遍历该参与者的相邻节点(即会议中的其他参与者),将他们标记为知道秘密。这个过程会继续传播,直到所有在这次会议中能够知道秘密的人都被更新。
103+
104+
当所有会议处理完毕后,遍历 $\textit{vis}$ 数组,将所有知道秘密的人的编号加入结果列表并返回。
105+
106+
时间复杂度 $(m \times \log m + n)$,空间复杂度 $O(n)$。其中 $m$ 和 $n$ 分别是会议数量和专家数量。
93107

94108
<!-- tabs:start -->
95109

@@ -137,8 +151,9 @@ class Solution {
137151
Arrays.sort(meetings, Comparator.comparingInt(a -> a[2]));
138152
for (int i = 0; i < m;) {
139153
int j = i;
140-
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2]; ++j)
141-
;
154+
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2];) {
155+
++j;
156+
}
142157
Map<Integer, List<Integer>> g = new HashMap<>();
143158
Set<Integer> s = new HashSet<>();
144159
for (int k = i; k <= j; ++k) {
@@ -156,7 +171,7 @@ class Solution {
156171
}
157172
while (!q.isEmpty()) {
158173
int u = q.poll();
159-
for (int v : g.getOrDefault(u, Collections.emptyList())) {
174+
for (int v : g.getOrDefault(u, List.of())) {
160175
if (!vis[v]) {
161176
vis[v] = true;
162177
q.offer(v);
@@ -189,8 +204,9 @@ public:
189204
});
190205
for (int i = 0, m = meetings.size(); i < m;) {
191206
int j = i;
192-
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2]; ++j)
193-
;
207+
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2];) {
208+
++j;
209+
}
194210
unordered_map<int, vector<int>> g;
195211
unordered_set<int> s;
196212
for (int k = i; k <= j; ++k) {
@@ -201,9 +217,11 @@ public:
201217
s.insert(y);
202218
}
203219
queue<int> q;
204-
for (int u : s)
205-
if (vis[u])
220+
for (int u : s) {
221+
if (vis[u]) {
206222
q.push(u);
223+
}
224+
}
207225
while (!q.empty()) {
208226
int u = q.front();
209227
q.pop();
@@ -217,9 +235,11 @@ public:
217235
i = j + 1;
218236
}
219237
vector<int> ans;
220-
for (int i = 0; i < n; ++i)
221-
if (vis[i])
238+
for (int i = 0; i < n; ++i) {
239+
if (vis[i]) {
222240
ans.push_back(i);
241+
}
242+
}
223243
return ans;
224244
}
225245
};
@@ -278,48 +298,57 @@ func findAllPeople(n int, meetings [][]int, firstPerson int) []int {
278298

279299
```ts
280300
function findAllPeople(n: number, meetings: number[][], firstPerson: number): number[] {
281-
let parent: Array<number> = Array.from({ length: n + 1 }, (v, i) => i);
282-
parent[firstPerson] = 0;
301+
const vis: boolean[] = Array(n).fill(false);
302+
vis[0] = true;
303+
vis[firstPerson] = true;
283304

284-
function findParent(index: number): number {
285-
if (parent[index] != index) parent[index] = findParent(parent[index]);
286-
return parent[index];
287-
}
305+
meetings.sort((x, y) => x[2] - y[2]);
288306

289-
let map = new Map<number, Array<Array<number>>>();
290-
for (let meeting of meetings) {
291-
const time = meeting[2];
292-
let members: Array<Array<number>> = map.get(time) || new Array();
293-
members.push(meeting);
294-
map.set(time, members);
295-
}
296-
const times = [...map.keys()].sort((a, b) => a - b);
297-
for (let time of times) {
298-
// round 1
299-
for (let meeting of map.get(time)) {
300-
let [a, b] = meeting;
301-
if (!parent[findParent(a)] || !parent[findParent(b)]) {
302-
parent[findParent(a)] = 0;
303-
parent[findParent(b)] = 0;
307+
for (let i = 0, m = meetings.length; i < m; ) {
308+
let j = i;
309+
while (j + 1 < m && meetings[j + 1][2] === meetings[i][2]) {
310+
++j;
311+
}
312+
313+
const g = new Map<number, number[]>();
314+
const s = new Set<number>();
315+
316+
for (let k = i; k <= j; ++k) {
317+
const x = meetings[k][0];
318+
const y = meetings[k][1];
319+
320+
if (!g.has(x)) g.set(x, []);
321+
if (!g.has(y)) g.set(y, []);
322+
323+
g.get(x)!.push(y);
324+
g.get(y)!.push(x);
325+
326+
s.add(x);
327+
s.add(y);
328+
}
329+
330+
const q: number[] = [];
331+
for (const u of s) {
332+
if (vis[u]) {
333+
q.push(u);
304334
}
305-
parent[findParent(a)] = parent[findParent(b)];
306335
}
307-
// round 2
308-
for (let meeting of map.get(time)) {
309-
let [a, b] = meeting;
310-
if (!parent[findParent(a)] || !parent[findParent(b)]) {
311-
parent[findParent(a)] = 0;
312-
parent[findParent(b)] = 0;
313-
} else {
314-
parent[a] = a;
315-
parent[b] = b;
336+
337+
for (const u of q) {
338+
for (const v of g.get(u)!) {
339+
if (!vis[v]) {
340+
vis[v] = true;
341+
q.push(v);
342+
}
316343
}
317344
}
345+
346+
i = j + 1;
318347
}
319348

320-
let ans = new Array<number>();
321-
for (let i = 0; i <= n; i++) {
322-
if (!parent[findParent(i)]) {
349+
const ans: number[] = [];
350+
for (let i = 0; i < n; ++i) {
351+
if (vis[i]) {
323352
ans.push(i);
324353
}
325354
}

solution/2000-2099/2092.Find All People With Secret/README_EN.md

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,21 @@ Thus, people 0, 1, 2, 3, and 4 know the secret after all the meetings.
8888

8989
<!-- solution:start -->
9090

91-
### Solution 1
91+
### Solution 1: Simulation + Graph Traversal
92+
93+
The core idea of this problem is to find all people who eventually know the secret by simulating the propagation process through meetings. We can treat each meeting as an edge in an undirected graph, where each participant is a node in the graph, and the meeting time is the "timestamp" of the edge connecting the nodes. At each time point, we traverse all meetings and use Breadth-First Search (BFS) to simulate the propagation of the secret.
94+
95+
We create a boolean array $\textit{vis}$ to record whether each person knows the secret. Initially, $\textit{vis}[0] = \text{true}$ and $\textit{vis}[\textit{firstPerson}] = \text{true}$, indicating that person 0 and $\textit{firstPerson}$ already know the secret.
96+
97+
We first sort the meetings by time to ensure that we process meetings in the correct order during each traversal.
98+
99+
Next, we process each group of meetings at the same time. For each group of meetings at the same time (i.e., $\textit{meetings}[i][2] = \textit{meetings}[i+1][2]$), we treat them as events occurring at the same moment. For each meeting, we record the relationships between participants and add these participants to a set.
100+
101+
Then, we use BFS to propagate the secret. For all participants at the current time point, if any of them already know the secret, we will traverse the adjacent nodes of that participant (i.e., other participants in the meeting) through BFS and mark them as knowing the secret. This process continues to propagate until all people who can know the secret at this meeting are updated.
102+
103+
When all meetings are processed, we traverse the $\textit{vis}$ array, add the IDs of all people who know the secret to the result list, and return it.
104+
105+
The time complexity is $O(m \times \log m + n)$, and the space complexity is $O(n)$, where $m$ and $n$ are the number of meetings and the number of experts, respectively.
92106

93107
<!-- tabs:start -->
94108

@@ -136,8 +150,9 @@ class Solution {
136150
Arrays.sort(meetings, Comparator.comparingInt(a -> a[2]));
137151
for (int i = 0; i < m;) {
138152
int j = i;
139-
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2]; ++j)
140-
;
153+
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2];) {
154+
++j;
155+
}
141156
Map<Integer, List<Integer>> g = new HashMap<>();
142157
Set<Integer> s = new HashSet<>();
143158
for (int k = i; k <= j; ++k) {
@@ -155,7 +170,7 @@ class Solution {
155170
}
156171
while (!q.isEmpty()) {
157172
int u = q.poll();
158-
for (int v : g.getOrDefault(u, Collections.emptyList())) {
173+
for (int v : g.getOrDefault(u, List.of())) {
159174
if (!vis[v]) {
160175
vis[v] = true;
161176
q.offer(v);
@@ -188,8 +203,9 @@ public:
188203
});
189204
for (int i = 0, m = meetings.size(); i < m;) {
190205
int j = i;
191-
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2]; ++j)
192-
;
206+
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2];) {
207+
++j;
208+
}
193209
unordered_map<int, vector<int>> g;
194210
unordered_set<int> s;
195211
for (int k = i; k <= j; ++k) {
@@ -200,9 +216,11 @@ public:
200216
s.insert(y);
201217
}
202218
queue<int> q;
203-
for (int u : s)
204-
if (vis[u])
219+
for (int u : s) {
220+
if (vis[u]) {
205221
q.push(u);
222+
}
223+
}
206224
while (!q.empty()) {
207225
int u = q.front();
208226
q.pop();
@@ -216,9 +234,11 @@ public:
216234
i = j + 1;
217235
}
218236
vector<int> ans;
219-
for (int i = 0; i < n; ++i)
220-
if (vis[i])
237+
for (int i = 0; i < n; ++i) {
238+
if (vis[i]) {
221239
ans.push_back(i);
240+
}
241+
}
222242
return ans;
223243
}
224244
};
@@ -277,48 +297,57 @@ func findAllPeople(n int, meetings [][]int, firstPerson int) []int {
277297

278298
```ts
279299
function findAllPeople(n: number, meetings: number[][], firstPerson: number): number[] {
280-
let parent: Array<number> = Array.from({ length: n + 1 }, (v, i) => i);
281-
parent[firstPerson] = 0;
300+
const vis: boolean[] = Array(n).fill(false);
301+
vis[0] = true;
302+
vis[firstPerson] = true;
282303

283-
function findParent(index: number): number {
284-
if (parent[index] != index) parent[index] = findParent(parent[index]);
285-
return parent[index];
286-
}
304+
meetings.sort((x, y) => x[2] - y[2]);
287305

288-
let map = new Map<number, Array<Array<number>>>();
289-
for (let meeting of meetings) {
290-
const time = meeting[2];
291-
let members: Array<Array<number>> = map.get(time) || new Array();
292-
members.push(meeting);
293-
map.set(time, members);
294-
}
295-
const times = [...map.keys()].sort((a, b) => a - b);
296-
for (let time of times) {
297-
// round 1
298-
for (let meeting of map.get(time)) {
299-
let [a, b] = meeting;
300-
if (!parent[findParent(a)] || !parent[findParent(b)]) {
301-
parent[findParent(a)] = 0;
302-
parent[findParent(b)] = 0;
306+
for (let i = 0, m = meetings.length; i < m; ) {
307+
let j = i;
308+
while (j + 1 < m && meetings[j + 1][2] === meetings[i][2]) {
309+
++j;
310+
}
311+
312+
const g = new Map<number, number[]>();
313+
const s = new Set<number>();
314+
315+
for (let k = i; k <= j; ++k) {
316+
const x = meetings[k][0];
317+
const y = meetings[k][1];
318+
319+
if (!g.has(x)) g.set(x, []);
320+
if (!g.has(y)) g.set(y, []);
321+
322+
g.get(x)!.push(y);
323+
g.get(y)!.push(x);
324+
325+
s.add(x);
326+
s.add(y);
327+
}
328+
329+
const q: number[] = [];
330+
for (const u of s) {
331+
if (vis[u]) {
332+
q.push(u);
303333
}
304-
parent[findParent(a)] = parent[findParent(b)];
305334
}
306-
// round 2
307-
for (let meeting of map.get(time)) {
308-
let [a, b] = meeting;
309-
if (!parent[findParent(a)] || !parent[findParent(b)]) {
310-
parent[findParent(a)] = 0;
311-
parent[findParent(b)] = 0;
312-
} else {
313-
parent[a] = a;
314-
parent[b] = b;
335+
336+
for (const u of q) {
337+
for (const v of g.get(u)!) {
338+
if (!vis[v]) {
339+
vis[v] = true;
340+
q.push(v);
341+
}
315342
}
316343
}
344+
345+
i = j + 1;
317346
}
318347

319-
let ans = new Array<number>();
320-
for (let i = 0; i <= n; i++) {
321-
if (!parent[findParent(i)]) {
348+
const ans: number[] = [];
349+
for (let i = 0; i < n; ++i) {
350+
if (vis[i]) {
322351
ans.push(i);
323352
}
324353
}

solution/2000-2099/2092.Find All People With Secret/Solution.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ class Solution {
88
});
99
for (int i = 0, m = meetings.size(); i < m;) {
1010
int j = i;
11-
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2]; ++j)
12-
;
11+
for (; j + 1 < m && meetings[j + 1][2] == meetings[i][2];) {
12+
++j;
13+
}
1314
unordered_map<int, vector<int>> g;
1415
unordered_set<int> s;
1516
for (int k = i; k <= j; ++k) {
@@ -20,9 +21,11 @@ class Solution {
2021
s.insert(y);
2122
}
2223
queue<int> q;
23-
for (int u : s)
24-
if (vis[u])
24+
for (int u : s) {
25+
if (vis[u]) {
2526
q.push(u);
27+
}
28+
}
2629
while (!q.empty()) {
2730
int u = q.front();
2831
q.pop();
@@ -36,9 +39,11 @@ class Solution {
3639
i = j + 1;
3740
}
3841
vector<int> ans;
39-
for (int i = 0; i < n; ++i)
40-
if (vis[i])
42+
for (int i = 0; i < n; ++i) {
43+
if (vis[i]) {
4144
ans.push_back(i);
45+
}
46+
}
4247
return ans;
4348
}
44-
};
49+
};

0 commit comments

Comments
 (0)