《剑指offer》刷题——【时间效率】面试题39:数组中出现次数超过一半的数字(java实现)

一、题目描述

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

二、题目分析

方法一:O(nlogn)

  • 给数组排序
  • 统计出每个数字出现的次数

方法二:基于Partition函数的时间复杂度为O(n)–会修改数组

  • 把数组排序,排序后位于数组中间的数字一定是那个出现次数超过一半的数字,即将问题转化为数组中第n/2大的数字
  • 受快排的启发,O(n)得到数组中第k大的数字
    • 先在数组中随机选择一个数字,然后调整数字的顺序,使得比选中的数字小的数字都排在它的左边,比选中的数字大的数字都排在它的右边
    • 如果选中的数字的下标刚好是 n/2,那么这个数字就是数组的中位数
    • 如果选中的数字的下标大于 n/2,那么中位数应该位于它的左边,接着在它的左边部分的数组中查找
    • 如果选中的数字的下标小于n/2,那么中位数应该位于它的右边,接着在它的右边部分的数组中查找
public class Solution {
   
    boolean inputInvalid = false;//标记输入无效
    public int MoreThanHalfNum_Solution(int [] array) {
   
        //判断输入的数组是否无效
        if(CheckInvalidArray(array)){
   
            return 0;
        }
        
        int mid = array.length >> 1;//中位数下标
        int start = 0;//开始编号
        int end = array.length-1;//末尾编号
        //选取基准元素,将比基准元素小的都放在基准元素左边,比基准元素大的都放在基准元素右边,
        //并返回基准元素的下标
        int index = Partition(array, start, end);
        //找中位数
        while(index != mid){
   
            //如果选中的数字下标大于N/2,则中位数应该位于左边
            if(index > mid){
   
                //在左边部分查找,终止索引修改为选中数字下标的前一位置
                end = index-1;
                index = Partition(array, start,end);
            }
            //如果选中的数字下标小于N/2,则中位数应该位于右边
            else{
   
                //右边部分查找,起始索引修改为选中数字下标的后一位置
                start = index +1
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值