编程题:数组中出现超数组长度一半的数字

数组中出现超数组长度一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

思路

  最平平无奇的方法是map(数值,出现次数)一一遍历统计。

  然而超过一半这个是否有什么特殊之处呢?如果有一个数值A出现超数组长度的一半,那么数组中必定有超过一半的位置是A,剩下不到一半的位置不是A。

 /*数组中出现超数组长度一半的数字*/
   //平平无奇循规蹈矩的方法,计数,可广泛使用,不限制于长度超一半
    public int MoreThanHalfNum_Solution(int [] array) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<array.length;i++){
            if(map.containsKey(array[i])){
                map.put(array[i],map.get(array[i])+1);
            }else{
                map.put(array[i],1);
            }
           // System.out.println(map);
            if(map.get(array[i])>array.length/2){
                return array[i];
            }
            if(map.keySet().size()-1>array.length/2){
                return 0;
            }
        }
        return 0;

    }
    /*别人的第一的代码(深度探索了规律):
    若是某个数字出现的次数大于一半,那么数组中必然有一处该数字出现的次数>其他数字出现的次数
    * 譬如{1,2,3,1,1,1,5,6,\7\},一开始一个1,对2,3会被替代,但是若要存在超一半的数字,我后面必须补两个1,补了三个1之后,1的长度为4,那么数组长度不得超过8,
    * 后面最多再补2两不同的数组才不会超过8,但同时无法覆盖1
    * */
    public int MoreThanHalfNum_Solution2(int [] array) {
        if (array.length == 0) {
            return 0;
        }
        int temp = array[0];
        int count = 1;
        for (int i = 1; i < array.length; i++) {
            if (array[i] == temp) {
                count++;
            } else {
                count--;
            }
            if (count == 0) {
                temp = array[i];
                count = 1;
            }
        }
        count = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == temp) {
                count++;
            }
        }
        return count > array.length / 2 ? temp : 0;
    }

 

posted @ 2021-04-25 10:17  l.w.x  阅读(83)  评论(0编辑  收藏  举报