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

题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2;
思路:
方法一:
将数组排序,取中位数,查看其出现次数。若大于数组长度的一半则输出.由于需要排序,因此时间复杂度为O(nlogn)
方法二:
遍历数字的时候保存两个值,一个是数字的值,另一个是其出现的次数。当我们遍历到一个数字的时候,如果他跟我们之前保存的数字一致,则次数加一,否则次数减一。当次数为0时,保存下一个数字并把次数设为一,由于我们要找的数字占所有次数一半还要多,所以肯定是最后留下的值。当遍历完成时,遍历原数组数一下该数出现的次数,若大于数组大小一半即为要求数字。该方法时间复杂度为O(n)
方法三:
一次快排partition我们随机选择一个数字,大于这个数字的在这个数字右边,小于这个数字的在这个数字左边。最后返回该数字序号index,若index小于n/2,则继续在数组右边查找。若大于,则在左边找。当index等于数组长度一半时,返回对应数字即可。该方法时间复杂度同样为O(n)。

import java.lang.reflect.Array;
import java.util.Arrays;

public class Solution {
    //方法一:
    // 将数组排序,取中位数,查看其出现次数
    public static int MoreThanHalfNumber(int[] array)
    {
        if (array.length==0||array==null)
            return -1;
        Arrays.sort(array);
        int middle = array.length/2;
        int count = 0;
        for (int i = 0; i <array.length ; i++) {
            if (array[i]==middle)
                count++;
        }
        if (count>array.length/2)
            return middle;
        else return -1;
    }
//    方法二:
//    遍历数字的时候保存两个值,一个是数字的值,另一个是其出现的次数
//    当我们遍历到一个数字的时候,如果他跟我们之前保存的数字一致,则次数加一,否则次数减一。
//     当次数为0时,保存下一个数字并把次数设为一,由于我们要找的数字占所有次数一半还要多,所以可定是最后留下的值。
//     当遍历完成时,遍历原数组数一下该数出现的次数,若大于数组大小一半即为要求数字
    public static int MoreThanHalf(int[] array)
    {
        if (array.length==0||array==null)
            return -1;
        if (array.length==2)
        {
            if (array[0]==array[1])
                return array[0];
            else return -1;
        }
        int num = array[0];
        int count =1;
        for (int i = 1; i <array.length ; i++) {
            if (array[i]==num)
                count++;
            if (array[i]!=num)
                count--;
            if (count==0){
                if (i==array.length-1)
                    return -1;
                else {
                    num = array[i+1];
                    count++;
                }
            }
        }
        for (int i = 0; i <array.length ; i++) {
            if (array[i]==num)
                count++;
        }
        if (count>array.length/2)
            return num;
        else return -1;
    }
//    方法三:一次快排patition
//    我们随机选择一个数字,大于这个数字的在这个数字右边,小于这个数字的在这个数字左边。最后返回该数字序号index,
//     若index小于n/2,则继续在数组右边查找
//    若大于,则在左边找
    public static int MoreThanHalfNum(int[] array)
    {
        if (array==null||array.length==0)
            return -1;
        if (array.length==2)
        {
            if (array[0]==array[1])
                return array[0];
            else return -1;
        }
        partitionArr(array,0,array.length-1);
        return array[array.length/2];
    }
    public static void partitionArr(int[] array,int left,int right)
    {
        int index = partition(array,left,right);
        if (index==array.length/2)
            return ;
        else
        if (index<array.length/2)
            partitionArr(array,index+1,right);
        else
            partitionArr(array,left,index-1);
    }
    public static int partition(int[] array,int left,int right)
    {
        int p=left, small = left-1, big = right,pivot = array[right];
        while (p<big)
        {
            if (array[p]<=pivot)
                swap(array,++small,p++);
            else swap(array,--big,p);
        }
        swap(array,p,right);
        return p;
    }
    public static void swap(int[] array,int i,int j)
    {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值