出现次数超过一半的数

题意:给定n个整数,有n/2个数相同,另外的n/2个数互异,求出现超过一半的那个数。

分析:

用hashtable的方法可以O(n),但也需要O(n)的额外空间;

采用经典的“多数元素”中的算法,可以O(n),且空间为O(1)。有没有更好的方法呢?

可以采用概率方法,每次取两个数出来比较,直到发现两个相同的数。

#include<cstdio>
#include<cstdlib>

int main()
{
    int a[] = {1, 2, 3, 4, 5, 6, 6, 6, 6, 6};
    int n = 8;
    int i = rand() % n;
    int j = rand() % n;
    while(a[i] != a[j])
    {
        i = rand() % n;
        j = rand() % n;
    }
    printf("%d
", a[i]);
}

复杂度:

任意两个数不同的概率 $p = frac{C_n^2 - C_{n/2}^2}{C_n^2} = 1 - frac{1}{4} cdot frac{n-2}{n-1}$

p约等于3/4,p^10= 0.056,也就是说10次还没出结果的概率为0.056,已经比较小了。

有趣的是,n越大,该概率越小。

原文地址:https://www.cnblogs.com/lfri/p/13283614.html