题:https://leetcode.com/problems/array-nesting/
题目大意
S[i] 表示一个集合,集合的第一个元素是 A[i],第二个元素是 A[A[i]],如此嵌套下去 直到 A[A[ … A[i]…]] == i。求最大的 S[i]。
思路
参考 并查集。
将由于 nums可以划分为 多个 闭集。 使用 并查集 将nums化为多个类。
从 遍历nums,若 该元素nums[i] 已经 属于 某个类,那么 跳过。否则,将从 nums[ … nums[i] …] 并为同一类。
但这个方法 会超时
class Solution {
int [] ufArr;
int findOp(int x){
int r = x;
while(ufArr[r]!=-1){
r = ufArr[r];
}
int p = x;
while(ufArr[p]!=-1){
int tmp = ufArr[p] ;
ufArr[p] = r;
p = tmp;
}
return r;
}
void unionOp(int a,int b){
a = findOp(a);
b = findOp(b);
if(a == b)
return;
a = ufArr[b];
}
public int arrayNesting(int[] nums) {
ufArr = new int[nums.length];
int maxCnt = 0 ;
for(int i = 0 ; i < ufArr.length ;i++)
ufArr[i] = -1;
for(int i = 0 ;i < nums.length;i++){
if(ufArr[i] == -1){
int n = i ;
int cnt = 1;
while(nums[n]!=i){
cnt++;
unionOp(nums[n],i);
n = nums[n];
}
maxCnt = Math.max(cnt,maxCnt);
}
}
return maxCnt;
}
}
从 遍历nums,若 该元素nums[i] 已经 遍历,那么 跳过。否则, 从 nums[ … nums[i] …] 访问,记录访问的长度。
class Solution {
public int arrayNesting(int[] nums) {
int maxCnt = 0 ;
for(int i = 0 ;i < nums.length;i++){
if(nums[i] != -1){
int n = i ;
int cnt = 0;
while(nums[n]!=-1){
cnt++;
int tmp = nums[n];
nums[n] = -1;
n = tmp;
}
maxCnt = Math.max(cnt,maxCnt);
}
}
return maxCnt;
}
}