数组中出现超过一半的数(复杂度O(n))

Posted ITAK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中出现超过一半的数(复杂度O(n))相关的知识,希望对你有一定的参考价值。

题目描述

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

解题思路

对于这个题,复杂度为 O ( n ∗ l o g n ) O(n*logn) O(nlogn) 的当然很简单了,将数组排序,取中间那个数,然后判断一下就行了。那么显然我们可以继续优化,要求条件是数字出现次数超过数组长度一半,换句话说就是,这个数字出现的次数比其它所有数字加起来出现的次数还多。那么我们根据这个进行撕烤,我们首先将第一个数看作是我们要求的数字即 tmp = numbers[0], cnt = 1,其中 t m p tmp tmp表示最后结果, c n t cnt cnt 表示个数,那么如果碰到下一个数,如果和 t m p tmp tmp 相等,那么 cnt++, 否则 cnt--, 显然当 cnt = 0 的时候,我们更新 t m p tmp tmp 为当前比较的数字,扫完一遍后,最后,我们判断 t m p tmp tmp 是否符合条件,如果符合条件,返回 t m p tmp tmp, 否则返回 0 0 0

代码如下

class Solution 
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) 
        int n = numbers.size();
        if(n == 0) return 0;
        int tmp = numbers[0], cnt = 1;
        for(int i=1; i<n; i++) 
            if(cnt == 0) 
                tmp = numbers[i];
                cnt = 1;
                continue;
            
            if(numbers[i] == tmp) cnt++;
            else cnt--;
        
        cnt = 0;
        for(int i=0; i<n; i++) 
            if(numbers[i] == tmp) cnt++;
        
        if(cnt > n/2) return tmp;
        return 0;
    
;

以上是关于数组中出现超过一半的数(复杂度O(n))的主要内容,如果未能解决你的问题,请参考以下文章

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

数组中有一个数字出现次数超过数组长度一半,找出这个数字(用C语言解决)。要求时间复杂度尽量小。

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

剑指offer-数组中出现次数超过一半的数字

[算法]数组中出现次数超过一半的数字

主元素