博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
主元素问题 减治法
阅读量:6526 次
发布时间:2019-06-24

本文共 930 字,大约阅读时间需要 3 分钟。

一个有n个元素的序列A中,出现次数大于n/2的元素称为主元素。现给定一个序列(保证存在主元素),求其主元素

一种思路是Boyer和Moore提出的减治法,可以在线性时间内求得主元素。如果不确定序列是否存在主元素,还需要再加一个线性的判断。

以下假设A的主元素存在,且出现了k次,则其他元素出现的次数为n - k,二者的差记为c = 2k-n。可知x为主元素当且仅当 c > 0。

考查序列A的长度为2m的前缀P,若其中某个元素 x 出现的次数达到m,则此时可减而治之,分析如下,参考了数据结构课本的“众数选取”部分:

  1. 若 x 确实为A的主元素,则A剪去前缀P后得到的后缀S,x的个数与非主元素的个数都减少了m,但二者的差仍为c,所以后缀S的主元素必然也是x。

  2. 若A的主元素不是 x,而是另一个元素y,那么剪去P后,至少除去了m个非主元素,所以后缀S中的c不会减小,S的主元素仍为y。

实现上,我们维护一个“差额计数器c” 和一个当前候选值maj ,初始化maj=A[0], c = 1。

从左到右扫描序列A,若A[i]==maj则c++,否则c--。当c减到0时,说明maj在当前的长度为2m的区间内恰好出现了m次,根据上面的分析,此时可以放心地剪去当前区间,只考虑后缀;所以我们置新的maj = A[i], c = 1,继续扫描至结尾,最终maj的值就是最后一个后缀的主元素。

若不确定原序列A是否存在主元素,可以扫描一遍统计下maj的个数。

题目嘛,找到了这么一道:

参考了 

1 int majorityElement(vector
& nums) { 2 int major; 3 for(int c=0, i=0; i < nums.size(); i++){ 4 if(c == 0){ 5 major = nums[i]; 6 c = 1; 7 }else 8 major == nums[i] ? c++ : c--; 9 }10 return major;11 }

 

转载地址:http://fwibo.baihongyu.com/

你可能感兴趣的文章
JVM分代垃圾回收策略的基础概念
查看>>
5G技术的5大猜想
查看>>
MongoDB 3.0(1):CentOS7 安装MongoDB 3.0服务
查看>>
别随便安装 Pokemon GO被曝藏恶意后门
查看>>
让数据会思考会说话,为出海企业提供多样化数据智能解决方案
查看>>
我眼中的自动化测试框架设计要点
查看>>
FLIF:自由的无损图像格式
查看>>
Google开源Inception-ResNet-v2,提升图像分类水准
查看>>
Opera 出售细节曝光:昆仑出资1.68亿美元
查看>>
CentOS 5.3 下快速安装配置 PPTP ××× 服务器
查看>>
产品经理学习总结之技术和设计篇
查看>>
23种设计模式(15):备忘录模式
查看>>
java基础学习总结——IO流
查看>>
iOS获取APP ipa 包以及资源文件
查看>>
CentOS 7 关闭启动防火墙
查看>>
Vue-选项卡切换
查看>>
linux网络命令
查看>>
nodejs ejs 请求路径和静态资源文件路径
查看>>
4.1 State Snapshot Transfer
查看>>
C++小代码
查看>>