Three solutions are provided here:Yong Xing | thinking Click Open Link
But I still want to record it.
Question:
A zero-indexed array a consisting of n different integers is given. the array contains all integers in the range [0 .. n−1]. sets s [k] For 0 ≤ k <n are defined as follows: s [k]
= {A [K], a [A [k], a [A [k],...}. sets s [k] are finite for each K.
Write a function:
Class solution {public int solution (INT [] );}
That, given an array a consisting of n integers, returns the size of the largest set S [k] for this array. The function shocould return 0 if the array is empty.
Note:
1) The array is empty and the element is negative.
2) A [A [I] crosses the border
3) discovery and termination of loops
4) All numbers in the array are different.
Instance: A = [1, 2, 3, 9, 6, 5, 8, 7, 4, 11,-1]
Loop A [4] = 6, a [6] = 8, a [8] = 4; A [5] = 5; A [7] = 7
Brute force solution:
a = [1,2,3,9,6,5,8,7,4,11,-1]flag = []n = len(a)def bfcounter(n): maxv = 0 j = 0 for k in xrange(n): count = 0 j = k while j <n and j >=0 and a[j]!=j and flag[j]==False: count+=1 flag[j]=True j =a[j] if j<n and j >=0 and a[j]==j: count+=1 if count >maxv: maxv = count return maxvfor k in xrange(n): flag.append(False)maxv = bfcounter(n)print "max is ",maxv
Use the flag to indicate whether the flag has been computed.
Another solution is recursive to reduce repeated computations. It is based on count (I) = 1 + count (A [I]). recursive computation also prevents loops.
Python code:
#!/usr/bin/pythonimport osimport sysa = [1,2,3,9,6,5,8,7,4,11,-1]n =len(a) flag = []def countSet(i,M,n): count =1 j=a[i] flag[i]=True if j >=n or j <0 or j ==i: M[i]=1 return count if j < n and j >=0 : if M[j]==0 and flag[j]==False:# not counted and not being computed. count = 1+countSet(j,M,n) elif M[j]==0 and flag[j]: # runs into a cycle,then stop count =1 M[j]=1 return count else: return count count = 1+M[j] M[i]=count return count return countdef main(): M = [] for k in xrange(n): M.append(0) flag.append(False) maxv = 0 for k in xrange(n): if M[k]==0: tmp = countSet(k,M,n) if tmp >maxv: maxv = tmp M[k]=tmp print "M:",M print "max set size is ",maxvif __name__=="__main__": main()
Note: After calculation, the statistics of some corresponding items in m are not necessarily the final result. For example, M [8] = 1, m [6] = 2, m [4] = 3 for the Ring of 4, 6, and 8. This is because of the function of flag .... (Is it too idiotic ......)
But! It does not affect the result. We only need the largest one ~
Query the solution:
Although it was not the first time I saw and found the explanation of the set, it was the first time I copied the relevant code ......
Python code
a = [1,2,3,9,6,5,8,7,4,11,-1]parent =[]n=len(a)num =[]maxv = 0def findset(x):#x is index?? while (x >=0 and x<n) and x != parent[x]: x=parent[x] if x <0 or x>=n: return -1 return parent[x]def unionset(i,j):#i is index ,j = a[i]?? global maxv x = findset(i) if x <0: return if j <0 or j >=n: num[x]+=1 return y = findset(j) if x ==y: return parent[x]=y num[y]+=num[x] num[x]=num[y] if maxv< num[x]: maxv=num[x]for i in xrange(n): num.append(1) parent.append(i)for i in xrange(n): unionset(i,a[i])print "num ",numprint "maxv ",maxv