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_1_week;
// 来自微软,真正考的时候阉割了难度
// 测试链接 : https://leetcode.com/problems/redundant-connection-ii/
public class Code03_RedundantConnectionII {
// [
// [1 , 5] 1 > 5
// [7 , 3] 7 > 3
// ]
// 边的数量 = 点的数量!
public static int[] findRedundantDirectedConnection(int[][] edges) {
// N是点的数量
// 点的编号1~N没有0
int N = edges.length;
// 并查集N个点去初始化每个点各自是一个集合
UnionFind uf = new UnionFind(N);
// pre[i] = 0 来到i节点是第一次
// pre[i] = 6 之前来过i是从6来的
int[] pre = new int[N + 1];
// 如果没有入度为2的点
// first second 都维持是null
// 如果有入度为2的点那么也只可能有一个
// 比如入度为2的点是5
// first = [3,5]
// second = [12,5]
int[] first = null;
int[] second = null;
// 有没有环!非常不单纯!含义复杂!
int[] circle = null;
for (int i = 0; i < N; i++) { // 遍历每条边!
int from = edges[i][0];
int to = edges[i][1];
if (pre[to] != 0) { // 不止一次来过to
first = new int[] { pre[to], to };
second = edges[i];
} else { // 第一次到达to
pre[to] = from;
if (uf.same(from, to)) {
circle = edges[i];
} else {
uf.union(from, to);
}
}
}
// 重点解析!这是啥???
// first != null
// 有入度为2的点
return first != null ? (circle != null ? first : second) : circle;
}
public static class UnionFind {
private int[] f;
private int[] s;
private int[] h;
public UnionFind(int N) {
f = new int[N + 1];
s = new int[N + 1];
h = new int[N + 1];
for (int i = 0; i <= N; i++) {
f[i] = i;
s[i] = 1;
}
}
private int find(int i) {
int hi = 0;
while (i != f[i]) {
h[hi++] = i;
i = f[i];
}
while (hi > 0) {
f[h[--hi]] = i;
}
return i;
}
public boolean same(int i, int j) {
return find(i) == find(j);
}
public void union(int i, int j) {
int fi = find(i);
int fj = find(j);
if (fi != fj) {
if (s[fi] >= s[fj]) {
f[fj] = fi;
s[fi] = s[fi] + s[fj];
} else {
f[fi] = fj;
s[fj] = s[fi] + s[fj];
}
}
}
}
}