数组中出现次数超过一半的数字

题目描述

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

Java代码实现

import java.util.Random;

//如果一个数字出现的次数超过数组长度的一半,那么按照顺序排列,位于中位数上的元素一定是该数字。所以
//这题就可以转换成一个求中位数,利用快排划分的思想可以实现算法复杂度为O(n)。
//如果直接排序,算法复杂度最少是O(NlogN)
public class MoreThanHalfNum {
    public static void main(String[] args){
        int[] a = {1,2,3,2,2,2,5,4,2};
        System.out.println(moreThanHalfNum(a));
    }

    public static int moreThanHalfNum(int[] array){
        if(array == null) return 0;

        int len = array.length;
        int middle = len >> 1; //取得中间位置的下标
        int start = 0;
        int end = len - 1;
        int index = Partition(array, start, end);
        while(index != middle){
            if(index > middle)
            {
                end = index - 1;
                index = Partition(array, start, end);
            }
            else
            {
                start = index + 1;
                index = Partition(array, start, end);
            }
        }
        int result = array[middle];
        if(!CheckMoreThanHalf(array, result))
            return 0;
        return result;

    }
    //检查位于中间位置的元素的个数是否超过数组长度的一半
    public static boolean CheckMoreThanHalf(int[] array, int result){
        int count = 0;
        for(int i = 0; i < array.length; i++){
            if(array[i] == result)
                count++;
        }
        if( (count*2) <= array.length) return false;
        return true;
    }

    //快排的 划分函数
    public static int Partition(int[] array, int start, int end){
        if(array == null) return 0;
        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 static void swap(int[] arr, int x ,int y)
    {
        int tmp = arr[x];
        arr[x] = arr[y];
        arr[y] = tmp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值