题目名称:最大集合
题目链接:
描述
给定一个1-N的排列A[1], A[2], … A[N],定义集合S[K] = {A[K], A[A[K]], A[A[A[K]]] … }。
显然对于任意的K=1…N,S[K]都是有限集合。
你能求出其中包含整数最多的S[K]的大小吗?
输入
第一行包含一个整数N。(1 <= N <= 100000)
第二行包含N个两两不同的整数,A[1], A[2], … A[N]。(1 <= A[i] <= N)
输出
最大的S[K]的大小。
样例输入
7
6 5 1 4 2 7 3
样例输出
4
解题思路
乍一眼看过去很简单,使用递归就可以解决问题,递归查找直到出现 A[k]=A[A[k]]为止,提交一次发现报错,查了半天发现应该是如下等式
A[start] =A[k] ,A[k]=A[A[k]]=A[A[A[k]]] =A[A[A[A …[k]]]]]
代码如下
public static int find(int x){
int tot=0,start=x;
while(start!=A[x]){
tot++;
x=A[x];
if(sum[x]!=0) break;
// System.out.print(" "+x);
}
// System.out.println();
return tot;
}
因为在循环过程中会重复访问某个A[k],使用sum[k]不为0标记,表示当访问到A[k]时进入循环,需要终止
完整代码
import java.util.Scanner;
public class Main {
public static int N = 100010;
public static int[] A=new int[N];
public static int[] sum=new int[N];
public static int n,a;
public static void main(String[] args){
Scanner in=new Scanner(System.in);
n=in.nextInt();
for(int i=1;i<=n;i++){
A[i]=in.nextInt();
}
int ans=0;
for(int i=1;i<=n;i++){
sum[A[i]]=find(A[i]);
if(ans<sum[i]){
ans=sum[i];
}
}
System.out.println(ans+1);
}
public static int find(int x){
int tot=0,start=x;
while(start!=A[x]){
tot++;
x=A[x];
if(sum[x]!=0) break;
// System.out.print(" "+x);
}
// System.out.println();
return tot;
}
}