查找之摩尔投票算法

  对于一个一位数组array[1,5,1,3,2,3,3,3,4,9,6,4,3,3,3,3],找出其中超过数组中一半长度的数。今天学到了一种是摩尔投票算法。其他的一种算法是首先对数组进行排序,这样从小到大,并且超过一半,该数存在的话一定在数组的正中间。这样最后对该数进行检查一遍,因为有可能对于刚好是等于一半的数。

  摩尔投票算法的思想是,首先定义一个majority和一个count,majority用来存放当前出现次数最多的数。如当majority等于第一个数后,count=1;然后majority与第二个数比较,如果相等,则count+1,否则count-1,如果减到count=0的时候,则说明该数在出现的当前序列已经不是出现次数最多的了,因此替换为当前的数。然后继续比较下去。最后同样要对得出来的数进行检验。

  

 1       public static int getValue(int[] gifts, int n) {
 3           int half=n/2; 5           int majority=0,count=0;
 6           for(int i:gifts){
 7               if(count==0){
 8                   majority=i;
 9                   count++;
10               }
11               else{
12                   if(majority!=i){  //当majority与当前数i不等时,
13                       count--;    //则计数count-1,如果count减一之后为0,则替换。
14                   }
15                   else{
16                       count++;
17                   }
18               }
19               if(count>half){
20                   return majority;
21               }
22           }
23           count=0;
24           for(int i:gifts){
25               if(majority==i){
26                   count++;
27               }
29           }
30           if(count>half){
31               return majority;
32           }
33           else return 0;
34       }    

  从找到数组中超过1/2的数变换为找到1/3的数,可以知道,数组中超过1/2的数最多一个,1/3的最多两个。

  

 1       public static String gettwomax(int[] a,int n){
 2           int m1=0,m2=0;
 3           int c1=0,c2=0;
 4           String maxTwoTimesNumber="";
 5           for(int i:a){
 6               if(m1==i){
 7                   c1++;
 8               }
 9               else if(m2==i){
10                   c2++;
11               }
12               else if(c1==0){
13                   m1=i;
14                   c1++;
15               }
16               else if(c2==0){
17                   m2=i;
18                   c2++;
19               }
20               else{
21                   c1--;
22                   c2--;
23               }
24           }
25           c1=0;
26           c2=0;
27           for(int i:a){
28               if(i==m1){
29                   c1++;
30               }
31               if(i==m2){
32                   c2++;
33               }
34           }
35           if(c1>n/3){
36               maxTwoTimesNumber+=m1;
37           }
38           if(c2>n/3){
39               maxTwoTimesNumber+=m2;
40           }
41           return maxTwoTimesNumber;
42           
43       }

  同样对于大于n/3的数,我们需要两个数来记录。比如数组[a,b,a,b,c],首先各自m1,m2,计数为0,当一个个条件去比较时,m1=a,c1=1,m2=b,c2=2,然后i等于a,i==m1,所以c1加一,然后i=b,c2加一,然后i=c,条件都不符合,则c1,c2都各自减一。若后续计数为0时,则把当前的数替换为m1或m2.

posted @ 2016-04-02 17:33  jeyfang  阅读(745)  评论(0编辑  收藏  举报