【趣味算法设计】众数问题&社会名流问题

这是在课上提的两个很有意思的问题,用比较笨的方法都可以轻松予以解决,但优化就是一件很有意思的事情。

众数问题:

给定数组A[1…n],找出其中出现次数严格大于

半数以上的元素或者报告这样的众数不存在

注:各元素之间不能比大小,只能比较彼此是否相等。

普通解法略去,下面给出O(n)算法的大体思路:

设置一个节点node,里面有element和counter两部分,前者用来盛放元素值,counter是计数器。


具体操作步骤:对给定数组从头到尾进行扫描,首先将element赋值为A[1],counter赋值为1,

如果counter为零则element赋值为当前元素,counter加1;

扫描过程中如果元素与element相等则counter加1;

如果元素与element不相等且counter大于1,则counter减1;

如果元素与element不相等且counter等于1,则counter置0;


整个过程结束后,再对该节点中存放的元素从头到尾进行一遍扫描,判断是否为众数。

关键在于:假如存在众数的话,剩下的那一个元素一定是所求众数,假如留下的元素不是众数,则该数组中一定没有众数。

由于前后只进行了两次扫描,所以复杂度为O(n)。

社会名流问题:

给定一个n×n邻接矩阵,确定是否存在一个i,
其满足在第i列所有项(除了第ii项)都为1,并
且第i行所有项(除了第ii项)都为0。


插话:这个其实就是有向图求源与汇的变形,O(n)算法非常经典,也是先找出一个来,如果有源肯定是该元素,该元素如果不是源,则就没有社会名流了

大致的算法思路:

随便取一个非对角线元素,比如Array[i][j],如果Array[i][j]=0成立,则j不是社会名流,于是删去第j行和第j列。

同样,如果Array[i][j]=1成立,则删去第i行和第i列;

总之,无论对应项取何值,都可以删去一行和一列,因此整个操作只耗费O(n)的时间。

重复此操作直至剩下最后一个元素。

最后,检验该元素是否为社会名流即可。

如果该元素不是,则该群人中不存在社会名流。


大体就是这样吧,可能有些地方说的不太清楚,不过确实感觉挺好玩的~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值