此處已經給出了三種解法:勇幸|Thinking 點擊開啟連結
但是我還是想記錄一下。
題目:
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[A[K]]], ... }. Sets S[K] are finite for each K.
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A consisting of N integers, returns the size of the largest set S[K] for this array. The function should return 0 if the array is empty.
注意:
1) 數組為空白,元素為負數
2)A[A[i]]越界
3)環路的發現和終止
4)數組中的所有數字各不相同
執行個體: a =[1,2,3,9,6,5,8,7,4,11,-1]
環路a[4]=6,a[6]=8,a[8]=4; a[5]= 5;a[7]=7
暴力解法:
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
使用flag標記是否已經被計算過,防止陷入環路中。
另外一種解法是遞迴的方法,減少重複計算。總的是基於 count(i)=1+count(a[i]),遞迴計算的同時也要防止陷入環路中。
python 代碼:
#!/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()
注意:計算完成後,M中某些對應項的統計量不一定是最終的結果。例如對4,6,8的這個環而言,M[8]=1,M[6]=2,M[4]=3 。這是由於flag的作用。。。。(我說的是不是太白癡了……)
but!反正不影響結果,我們只要最大的嘛~
並查集的解法:
雖然不是第一次看到並查集的講解,但是卻是第一次抄寫相關的代碼……
python 代碼
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