【算法】数组中出现次数超过一半的数字

来源:互联网 发布:网络pc蛋蛋赌博定罪 编辑:程序博客网 时间:2024/06/05 07:23

题目描述:

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

例如{2,1,3,2,2,2,2,5,4,2,2,2,2},由于数字2的个数超过了数组长度的一半,则输出2.


解题思路1:

数组排序后有一个特征:数组中如果有超过一半长度的数字,则排序之后位于数组中间的数字一定是超过一半的数字。也就是中位数。受快速排序的启发,随即找出一个数字,如果其最终位置位于n/2,则这个数字就是中位数。如果最终位置大于n/2,则中位数一定位于其左边,递归查找其左边。如果最终位置小于n/2,则位于数组右边,递归查找右边。

解题思路2:

数组中如果有超过一半长度的数字,则它出现的次数比其他所有数字的出现的总次数都要多。因此,遍历时保存两个值,一个是数组中的数字,一个是出现次数。当遍历到下一个数字时,如果下一个数字和当前数字相同则times++,如果和下一个数字不同,则times--;如果次数为0,则重新保存下一个数字并将times置为1.如果存在次数超过一半,最后一次置为1的数字,一定是出现次数超过一半的数字。


public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);        String a=in.nextLine();        String b[]=a.split(" ");        int temp[]=new int[b.length];        for(int i=0;i<b.length;i++){        temp[i]=Integer.valueOf(b[i]);        }        System.out.println(MoreThanHalf(temp,b.length));        System.out.println(MoreThanHalf2(temp,b.length));        }static int MoreThanHalf(int a[],int length){int middle=length/2;int star=0;int end=length-1;int index=partition(a,star,end);while(index!=middle){if(index>middle){end=index-1;index=partition(a,star,end);}else{star=index+1;index=partition(a,star,end);}}int times=0;int result=a[middle];for(int i=0;i<length;i++){//判断是否超过一半if(a[i]==result)times++;}if(times*2<=length)return -1;return result;}public static int partition(int[] a, int low, int high){                  int key = a[low];//基准元素,排序中会空出来一个位置          while(low<high){              while(low<high && a[high]>=key){//从high开始找比基准小的,与low换位置                  high--;              }              a[low]=a[high];              while(low<high && a[low]<=key){//从low开始找比基准大,放到之前high空出来的位置上                  low++;              }              a[high]=a[low];          }          a[low]=key;//此时low=high 是基准元素的位置,也是空出来的那个位置          return low;              } }


解题思路2代码:

static int MoreThanHalf2(int a[],int length){int result=a[0];int times=1;for(int i=1;i<length;i++){if(times==0){result=a[i];times=1;}else if(a[i]==result)times++;else times--;}int t=0;for(int i=0;i<length;i++){//判断是否超过一半if(a[i]==result)t++;}if(t*2<=length)return -1;return result;}