经典面试题16 - 数组中出现次数超过一半的数字

问题
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

例如: 输入一个长度为7的数组,

{1,2,2,2,5,4,2}

由于数字2在数组中出现了4次,超过数组长度的一半,因此输出2。如果不存在则输出0。

解答

首先说这是一道很经典的面试题,很多互联网公司都曾经采用过这个题目。

下面是对该题的分析思路:

  • 如果没有时间复杂度的要求, 我们可以对数组进行排序,排序后的数组,那么我们只要遍历一次就可以统计出每个数字出现的次数,这样也就能找出符合要求的数字。按照这个思路的时间复杂度是O(nlogn), 其中排序的时间复杂度是O(nlogn),遍历的时间复杂度O(n)。

  • 另一个思路是我们可以创建一个哈希表来消除排序的时间。哈希表的键值为数组中的数字,值为该数字对应的次数。有了这个哈希表之后,我们只需要遍历数组中的每个数字,找到它在哈希表中对应的位置并增加它出现的次数。这种哈希表的方法在数组的所有数字都在一个比较窄的范围内的时候很有效。

  • 最佳思路:数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。
    因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1;如果下一个数字和我们之前保存的数字不同,则次数减1。
    如果次数为0,我们需要保存下一个数字,并把次数置1。因为次数为0,表示前面是字符串计数抵消为0。

//Java源码
public int MoreThanHalfNum_Solution(int [] numbers) {
        int maxNum = 0;
        if(numbers.length==0)
            return maxNum;
        maxNum = numbers[0];
        int numCount = 1;
        for(int i=1;i<numbers.length-1;i++){
            if(numbers[i] == maxNum){
                numCount++;
            }else{
                numCount--;
                if(numCount == 0){
                    numCount = 1;
                    maxNum = numbers[i];
                }
            }
        }
        int total = 0;  
        for (int i = 0; i < numbers.length; i++) {  
            if (numbers[i] == maxNum) total++;  
        }  
        if (total * 2 <= numbers.length) {  
            return 0;
        }  
        else return maxNum ;
    }

上述源码可以在 这里 调试

推荐阅读

经典面试100题 - 持续更新中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 该文章总结自牛课网的在线算法课程(https://www.nowcoder.com/) 经典排序算法就是前面讲那几...
    锅与盆阅读 7,767评论 6 14
  • 作者:July、wuliming、pkuoliver 说明:本文分为三部分内容,第一部分为一道百度面试题Top K...
    cyj_ya阅读 841评论 0 0
  • 第一章 绪论 什么是数据结构? 数据结构的定义:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 第二章...
    SeanCheney阅读 5,835评论 0 19
  • 所有货币都需要一些方法来控制供应,并强制执行各种安全属性以防止作弊。在法定货币方面,像中央银行这样的组织控制货币供...
    Nutbox_Lab阅读 3,185评论 1 3
  • 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 解法:假设将数组排序,因为所求数字出现次数超...
    qmss阅读 408评论 0 0