x稱為一個長度為n的數組的a的主元素,如果這個數組里面等於x的元素的數目不少於n/2個。
例如,a={2,3,2,2,5,3,2,4,2},x=2就是這個主元素。給定包含n個元素的數組a,主元素問題就是判斷數組a是否包含一個主元素x。
三個方法實現:
方法一:
求中文書,主元素可定是中位數,否則該元素數量少於n/2則不是主元素;快速排序,然后確定中位數時間復雜度O(nlogn)
方法二:
分子思想:
若T中存在主元素,則將T分為兩個部分,T的主元素也必為兩部分中至少一部分的主元素,因此可用分治法。
將主元素划分為兩部分,遞歸地檢查兩部分有無主元素。算法如下:
a.若T只含有一個元素,則吃元素就是主元素,返回此數。
b.講T分為兩部分T1和T2(兩者元素個數相等或者差一),分別使用遞歸方法求其主元素m1和m2.
c.若m1和m2都存在且相等,則這個數就是T的主元素,返回此數。
d.若m1和m2都存在且不相等,則分別檢查者兩個數是否為T的主元素,若有,則返回此數,若無則返回空值。
e.若m1和m2只有一個存在,則檢查這個數是否為T的主元素,若是則返回此數,若否就返回空值。
f.若m1和m2都不存在,則T無主元素,返回空值。
方法三:
思路比較新穎,原理是如果一個元素中存在一個主元素(個數大余n/2),則同時刪除兩個不相等的數,這個主元素不會改變。
簡單的說就是一個大小為n的數組中存在一個元素的個數大余n/2,則如果用這個數組中其他的數和該主元素進行抵消的話,最后剩下的一定是主元素,因為主元素個數最多。
該方法可以在O(n)時間內找到主元素。十分高效。
方法一代碼:
import java.util.Arrays; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int[] a = {2,3,2,2,5,3,2,4,2}; int i = 0; Arrays.sort(a); int index = a.length/2; if(a[0]==a[index]||a[a.length-1]==a[index]){ System.out.println(a[index]); } } }
方法二代碼:
方法三代碼:
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int[] a = {3,5,4,3,3,3,2,3,2}; int mainE = mainElement(a, 9); System.out.println(mainE); } public static int mainElement(int[]num,int n){ int seed = num[0]; int count = 1; int i = 0; //取出主元素 for(i = 1; i<n;i++){ if(seed==num[i]){ count++; }else{ if(count>0){ count--; }else{ seed = num[i]; } } } //判斷取出的主元素是不是主元素 count = 0; for(i = 0;i<n;i++){ if(num[i] == seed){ count++; } } if(count >= n/2){ return seed; } return 0; } }