-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaximumInvitations.ts
63 lines (52 loc) · 2.19 KB
/
maximumInvitations.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
function maximumInvitations(favorite: number[]): number {
const n: number = favorite.length;
const reversedGraph: number[][] = Array.from({ length: n }, () => []);
// Create reversed graph
for (let person = 0; person < n; ++person) {
reversedGraph[favorite[person]].push(person);
}
// Helper function for BFS
const bfs = (startNode: number, visitedNodes: Set<number>): number => {
const queue: [number, number][] = [[startNode, 0]];
let maxDistance = 0;
while (queue.length > 0) {
const [currentNode, currentDistance] = queue.shift()!;
for (const neighbor of reversedGraph[currentNode]) {
if (visitedNodes.has(neighbor)) continue;
visitedNodes.add(neighbor);
queue.push([neighbor, currentDistance + 1]);
maxDistance = Math.max(maxDistance, currentDistance + 1);
}
}
return maxDistance;
};
let longestCycle = 0;
let twoCycleInvitations = 0;
const visited: boolean[] = Array(n).fill(false);
// Find all cycles
for (let person = 0; person < n; ++person) {
if (!visited[person]) {
const visitedPersons: Map<number, number> = new Map();
let current = person;
let distance = 0;
while (true) {
if (visited[current]) break;
visited[current] = true;
visitedPersons.set(current, distance++);
const nextPerson = favorite[current];
if (visitedPersons.has(nextPerson)) { // Cycle detected
const cycleLength = distance - visitedPersons.get(nextPerson)!;
longestCycle = Math.max(longestCycle, cycleLength);
if (cycleLength === 2) {
const visitedNodes = new Set<number>([current, nextPerson]);
twoCycleInvitations +=
2 + bfs(nextPerson, visitedNodes) + bfs(current, visitedNodes);
}
break;
}
current = nextPerson;
}
}
}
return Math.max(longestCycle, twoCycleInvitations);
};