【DFS】因为这里不包含重复元素,所以不会出现一个顶点连接多个顶点的情况,所以设置一个visit数组,对每个顶点dfs,如果这个顶点被访问过了,说明他组成了环。在对下一个顶点dfs的时候判一下是否已经访问过,如果访问过,说明已经在环中了。
其实这里改成这样就更好理解了
0 -> 5
1 -> 4
2 -> 0
3 -> 3
4 -> 1
5 -> 6
6 -> 2
其实就是一个无向图,找环而已
class Solution {
// dfs
public int arrayNesting(int[] nums) {
int[] visit = new int[nums.length];
int max = 0;
for (var i = 0; i < nums.length; i++) {
if (visit[i] == 1) continue;
int idx = i, t = 0;
while(true) {
if (visit[idx] == 1) {
max = Math.max(max, t);
break;
}
t++;
visit[idx] = 1;
idx = nums[idx];
}
}
return max;
}
}
【并查集】用并查集也可以找环,把在同一个环上的union起来,然后判每一个union的大小就行
class Solution {
int[] f = new int[100001];
public int ask(int x) {
if (x == f[x]) return x;
return f[x] = ask(f[x]);
}
public void union(int x, int y) {
f[ask(x)] = ask(y);
}
public int arrayNesting(int[] nums) {
int n = nums.length;
for (var i = 1; i <= n; i++) f[i] = i;
for (var i = 0; i < n; i++) union(nums[i], i);
int[] cnt = new int[n + 1];
int ans = 0;
for (var i = 0; i < n; i++) {
ans = Math.max(ans, ++cnt[ask(i)]);
}
return ans;
}
}