DS-008 順序表-尋找主元素
阿新 • • 發佈:2019-01-06
題目:已知一個整數序列A=(a0,a1,…,an-1),其中0≤ai<n(0≤i<n)。若存在ap1=ap2=…=apm=x且m>n/2(0≤pk<n,1≤k≤m),則稱x為A的主元素。例如A=(0,5,5,3,5,7,5,5),則5為主元素;又如A=(0,5,5,3,5,1,5,7),則A中沒有主元素。
假設A中的n個元素儲存在一個一維陣列中,請設計一個儘可能高效的演算法,找出A的主元素。若存在主元素,則輸出該元素;否則輸出-1。要求:
(1)給出演算法的基本設計思想。
(2)根據設計思想,採用C或C++或Java語言描述演算法,關鍵之處給出註釋。
(3)說明你所設計演算法的時間複雜度和空間複雜度。
分析:由題目中定義,主元素個數必須大於所有元素個數的一半,也可以說,主元素的個數比非元素個數之和還要多。
答:
(1)演算法思想:
選取備選主元素,用count記錄主元素個數和其他元素個數的差。初始時count為1,第一個元素為主元素,遇到主元素,count+1,遇到其他元素,count-1,count為0時,主元素定義在前半部分不滿足。如果存在主元素,必須在後半部分滿足定義,所以直接捨棄前半部分。將當前掃描的下一個元素暫定為主元素,count重新記為1,直到掃描完所有陣列。留下的那個元素有可能是主元素;統計上面得到的備選主元素的個數,驗證是否滿足主元素定義。
(2)演算法實現:
int Majority(int A[],int n){ int i,c,count=1; //c用來儲存候選主元素,count用來計數 c = A[0]; //設定A[0]位候選主元素 for(i=1;i<n;i++) //遍歷陣列,候選主元素是否滿足定義 if(A[i]==c) count++; //對A中的候選主元素計數 else if(count>0) //處理不是候選主元素的情況 count--; else{ //count=0,更換候選主元素,重新計數 c=A[i]; count=1; } if(count>0) for(i=count=0;i<n;i++) //統計候選主元素的實際出現次數 if(A[i]==c) count++; if(count>n/2) return c; //確認候選主元素 else return -1; //不存在主元素 }
(3)該演算法時間複雜度為O(n),空間複雜度為O(1)。
(如果上面的演算法太難想,不用糾結最優解,能解出來最重要)