第28题——数组中出现次数超过一半的数字

121 阅读2分钟

题目:

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

思路

解法一(常规):将数组排序,如果存在这样的数,那么中位数一定是这个数,array[mid]就是这个中位数,再遍历一遍这个数组,统计array[mid]出现的次数count,如果count>array.length/2,就说明找到了,否则不存在这样的数,返回0;

Java

package nowcoder;

import java.util.Arrays;

public class S28_MoreThanHalfNum {
    public int moreThanHalfNum(int[] array){
        if (array == null || array.length == 0)
            return 0;
        Arrays.sort(array);
        int mid = array[array.length>>1];
        int number = array[mid];
        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;
    }
    public static void main(String[] args){
        S28_MoreThanHalfNum s28 = new S28_MoreThanHalfNum();
        int[] array = {1,2,3,2,2,2,5,4,2};
        int result = s28.moreThanHalfNum(array);
        System.out.println(result);
    }
}

解法二: 利用hash

package nowcoder;

import java.util.HashMap;

public class S28_MoreThanHalfNum_Hash {
    public int moreThanHalfNum(int[] array){
        if (array.length==0)
            return 0;
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i=0;i<array.length;i++){
            Integer count = map.get(array[i]);
            if (count == null){
                map.put(array[i],1);
                count = 0;
            }
            else 
                map.put(array[i],count+1);
            if (count+1 >array.length/2)
                return array[i];
        }
        return 0;
    }
    public static void main(String[] args){
        S28_MoreThanHalfNum_Hash s28 = new S28_MoreThanHalfNum_Hash();
        int[] array = {1,2,3,2,2,2,5,4,2};
        int result = s28.moreThanHalfNum(array);
        System.out.println(result);
    }
}

解法三:O(n)

思想:一个玩具店有各种颜色的皮球,想找出一种球的个数是否超过了一半。依次传送这些球,第一个过来的球记为result,个数count=1.下面再依次传送剩下的球,如果count=0,则当前传送过来的球记为result,count++;如果count!=0,如果当前这个球和result的球一样,则count++,否则count--。最后若count>0,则可能有种球的个数超过一半,重新遍历一下统计result的个数,若其超过一半则返回result,否则返回0.

package nowcoder;

public class S28_MoreThanHalfNum_best {
    public int moreThanHalfNum(int[] array){
        if (array.length==0)
            return 0;
        int result = array[0];
        int count = 1;
        for (int i=1;i<array.length;i++){
            if (count == 0){
                result = array[i];
                count =1;
            }
            else {
                if (array[i]==result)
                    count++;
                else
                    count--;
            }
        }
        count = 0;
        for (int i=0;i<array.length;i++){
            if (array[i] == result)
                count++;
        }
        if (2*count > array.length)
            return result;
        else return 0;
    }
    public static void main(String[] args){
        S28_MoreThanHalfNum_best s28 = new S28_MoreThanHalfNum_best();
        int[] array = {1,2,2,2,3};
        int result = s28.moreThanHalfNum(array);
        System.out.println(result);
    }
}

Python

class MoreThanHalfNum:
    def moreThanHalfNum(self, array):
        if len(array) == 0:
            return 0
        result = array[0]
        count = 1
        for i in range(len(array)):
            if count == 0:
                result = array[i]
                count = 1
            else:
                if array[i] == result:
                    count += 1
                else:
                    count -= 1
        count = 0
        for i in range(len(array)):
            if array[i] == result:
                count += 1
        if count*2 > len(array):
            return result
        else:
            return 0
if __name__ == '__main__':
    test = MoreThanHalfNum()
    array = [1, 2, 2, 3, 7, 2, 3, 2, 8, 2, 9, 2, 2]
    print(test.moreThanHalfNum(array))