思路1:数组排序后,如果符合条件的数存在,则一定是数组中间那个数。否则,需要进行判断,看数组中的数是否有一半和中间的数相等,相等则存在符合条件的数,不存在则直接返回0

import java.util.Arrays;

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        Arrays.sort(array);
        int count=0;
        //记录数组中等于该数组中间索引的元素  
        for(int i=0;i<array.length;i++){
            if(array[i]==array[array.length/2]){
                count++;
            }
        }
        if(count>array.length/2){ //如果数量超过一半,则说明符合条件,否则返回0
            return array[array.length/2];
        }else{
            return 0;
        }

    }
}

思路2:不使用排序,(这个方法也叫摩尔投票法,有兴趣的可以去看看leetcode第169题,只是牛客上的题数组中可能出现没超过一半的数字)遍历数组过程中保存两个值:一个是数组中某一数字,另一个是次数。遍历到下一个数字时,若与保存数字相同,则次数加1,反之减1。若次数=0,则保存下一个数字,次数重新设置为1。由于要找的数字出现的次数比其他数字之和还多,那么要找的数字肯定是最后一次把次数设置为1的数字。(当一个数的出现次数比其他数出现次数的总和还多时,说明这个值是符合条件的)
友情提示:当一个数最终的time>0,并不意味着这个数就符合要求了,比如在数组{1,2,3,4,5,6,7,7,7,8,9,10,10}中,运行完for循环后,最终会记录数字10,并且time为2。这一操作只是尽可能的在找一个出现次数较多的数。因此还需要进行一轮判断if。在第二轮过程中,count才是计数,判断数组中的数是否等于这个找出来的数(因为在不满足的条件的情况下,找出来的这个数只是出现次数较多,而非最多),如果有一半以上等于这个数,就找到,否则,不存在。

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        //非法输入判断
        if(array == null || array.length <= 0)
            return 0;
        int times = 1;
        int number = array[0];
        //查看是否存在有可能次数大于数组长度一半的数字
        for(int i = 1; i < array.length; i++) {
            if(times <= 0) {
                number = array[i];
                times = 0;
            }
            if(array[i] == number) {
                times++;
            }
            else { 
                times--;
            }
        }
        //判断该数字次数是否大于数组长度一半
        if(times > 0) {
            int count = 0;
            for(int i = 0; i < array.length; i++) {
                if(array[i] == number)
                    count++;
            }
            if(count > array.length / 2)
                return number;
            else
                return 0;
        }
        else
            return 0;
    }
}

思路3:
中位数,又称中点数,中值。中位数是按顺序排列的一组数据中居于中间位置的数,即在这组数据中,有一半的数据比他大,有一半的数据比他小
如果这个数组的满足条件,那么他的出现次数超过一般的数字一定是中位数。所以找到数组的中位数,就找到了结果。而想找到一个数组的中位数,并且不通过排序的话。联想到快排中有一个核心方法即Partition函数

Partition函数的功能是可以在数组中任取一个数字,将数组中比该数字小的均放置在该数字左边,比该数字大的均放在该数字右边。最后返回该数字的下标small,并赋给index。此时,index的左边都比index小,右边都比index大(左边只保证小,并没有排序)
利用这个函数的特性:
1.设数组长度一半为middle。数组起点为start,终点为end。
2.若index大于middle,说明中位数在start到index之间。更新end = index - 1;
若index小于middle,说明中位数在index到end之间。更新start = index + 1;
若index等于middle,说明array[index]即为中位数。
3.判断取得的中位数是否满足次数大于长度一半。(这样的操作最终结果是获得了整个数组的中位数)
思路3不好的地方在于,更改了输入的数据,改变了输入的数组元素的位置,并且通过Pratition找到的是中位数,中位数不一定是结果!{1,2,3,4,5,6,7,7,8}的中位数是5

import java.util.Random;
public class Solution { 
    public int MoreThanHalfNum_Solution(int[] array) {
        int start = 0, end = array.length - 1;
        int index = Partition(array, start, end);
        int middle = array.length / 2;
        while(index != middle) {
            if(index > middle) {
                end = index - 1;
                index = Partition(array, start, end);
            }   
            else {
                start = index + 1;
                index = Partition(array, start, end);
            }

        }
        int times = 0;
        for(int i = 0; i < array.length; i++) {
            if(array[i] == array[index]) 
                times++;
        }
        if(times > array.length / 2)
            return array[index];
        else
            return 0;
    }
    public int Partition(int[] array, int start, int end) {
        Random rand = new Random(); 
        int index = rand.nextInt(end - start + 1) + start;
      //这里使用随机数是优化,若选取的不合理,会导致时间复杂度增加
        Swap(array, index, end);
        int small = start - 1;
        for(index = start; index < end; index++) {
            if(array[index] < array[end]) {
                small++;
                if(small != index) 
                    Swap(array, small, index);
            }
        }
        small++;
        Swap(array, small, end);
        return small;
    }
    public void Swap(int[] array, int a, int b) {
        int tmp;
        tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }
}

总结:思路1是排序,排完序后整个数组都很直观。思路2是尽量找出现次数较多的数,如果出现次数超过一半,一定可以出来,而找出来的数不能保证是出现次数最多。思路3是不通过排序,找数组的中位数,然而破坏了原数组的顺序。