You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2021_12_2_week;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
// 链接测试 : https://leetcode.com/problems/find-all-people-with-secret/
public class Code01_FindAllPeopleWithSecret {
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
// 0~n-1号专家各自建立小集合
// (0, firstPerson)合在一起,作为知道秘密的集合
UnionFind uf = new UnionFind(n, firstPerson);
int m = meetings.length;
Arrays.sort(meetings, (a, b) -> a[2] - b[2]);
// [1,7,1] [2,4,2] [3,6,2]
// 1,7 2,4 3,6
int[] help = new int[m << 1];
help[0] = meetings[0][0];
help[1] = meetings[0][1];
int size = 2;
for (int i = 1; i < m; i++) {
// i 2
if (meetings[i][2] != meetings[i - 1][2]) {
share(help, size, uf);
help[0] = meetings[i][0];
help[1] = meetings[i][1];
size = 2;
} else {
help[size++] = meetings[i][0];
help[size++] = meetings[i][1];
}
}
share(help, size, uf);
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (uf.know(i)) {
ans.add(i);
}
}
return ans;
}
public static void share(int[] help, int size, UnionFind uf) {
for (int i = 0; i < size; i += 2) {
uf.union(help[i], help[i + 1]);
}
for (int i = 0; i < size; i++) {
if (!uf.know(help[i])) {
uf.isolate(help[i]);
}
}
}
public static class UnionFind {
public int[] father;
public boolean[] sect;
public int[] help;
public UnionFind(int n, int first) {
father = new int[n];
sect = new boolean[n];
help = new int[n];
for (int i = 1; i < n; i++) {
father[i] = i;
}
father[first] = 0;
sect[0] = true;
}
private int find(int i) {
int hi = 0;
while (i != father[i]) {
help[hi++] = i;
i = father[i];
}
for (hi--; hi >= 0; hi--) {
father[help[hi]] = i;
}
return i;
}
public void union(int i, int j) {
int fatheri = find(i);
int fatherj = find(j);
if (fatheri != fatherj) {
father[fatherj] = fatheri;
sect[fatheri] |= sect[fatherj];
}
}
public boolean know(int i) {
return sect[find(i)];
}
public void isolate(int i) {
father[i] = i;
}
}
}