出现次数超过一半的数

题意:给定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\n", a[i]);
}
复制代码

复杂度:

任意两个数不同的概率 p=Cn2Cn/22Cn2=114n2n1

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

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

而尝试次数的期望值X:1*(1-p) + 2*p(1-p) + 3*p^2*(1-p) + 4*p^3*(1-p) + ... = 1/(1-p),啊这,好像能直接看出结果,X*(1-p)=1,X=1/(1-p),所以n越大,尝试次数越小。。

posted @   Rogn  阅读(464)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2019-07-11 P3254——DP&&入门
2019-07-11 P3384——树链剖分&&模板
2019-07-11 树链剖分模板
点击右上角即可分享
微信分享提示