Majority Element问题---Moore's voting算法
Leetcode上面有这么一道难度为easy的算法题:找出一个长度为n的数组中,重复次数超过一半的数,假设这样的数一定存在。O(n2)和O(nlog(n))(二叉树插入)的算法比较直观。Boyer–Moore majority vote algorithm在1980年提出,用O(1)空间和O(n)时间解决了这个问题。这个算法的思路:由于重复频率超过 floor(n/2)的数字只有一个,等价于与其余数字出现频率的差大于零。当遍历整个数组时,使用变量candidate记录当前重复次数最多的数,count计算candidate重复多余的次数。以下为具体实现:
int count = ;
int candidate;
for(int i = ; i < n; ++i)
{
if(count == )
{
candidate = a[i];
}
if(candidate == a[i])
++count;
else
--count;
}
在遍历过程中,当前元素与candidate相同则投支持票,否则投反对票。当count状态为0时,说明之前的子数组中不存在重复次数超过一半的数,遍历余下的数组成为原问题的子问题。若该数不一定存在,那么需要再一次遍历数组,鉴证找到的元素是否符合条件。
进一步思考,若要返回出现次数大于k次的所有元素,即为iceburg query问题。iceburg query的想法其实可以向其名字一样形象。假设将数组中所有元素转化为histogram,高度为出现的频率,那么每个筒子有高有低,就像冰山一样。之后不断的下降冰山,下降k次。那么剩下还留在水面上的就是满足要求的元素。直接这样求解问题需要多次遍历数组内的元素O(log(n!) + log(nk))。
当然也可以遍历两次。由于满足条件的元素出现次数大于k,那么整个数组中至多存在n/k个。因此在第一次遍历的时候,维护一个数组a,若当前元素不存在数组中,则插入该元素和出现次数1。然后判断数组大小是否超过n/k。如果超过则所有元素下降一个,并且除去出现次数为0的元素。第二次遍历,查看是否a中的元素出现次数都大于k(因为满足条件的元素个数可以小于n/k)。
unordered_map m;
// first pass
for(i = 0; i < n; ++i)
{
if(m.find(nums[i]) == m.end())
{
m.insert(pair<int, int>(nums[i], 1));
}
else
{
++m[ nums[i] ];
} if(m.size() > n / k)
{
for(auto it = m.begin(); it != m.end();++it)
{
--(it -> second);
if(!(it -> second))
m.erase(it++);
}
}
} // second pass
for(auto &x: m)
m -> second = 0; for(i = 0; i < n; ++i)
{
++m[ nums[i] ];
if(m[nums[i]] > k)
{
v.push_back(nums[i]);
}
}
Majority Element问题---Moore's voting算法的更多相关文章
- 【算法31】寻找数组的主元素(Majority Element)
题外话 最近有些网友来信问我博客怎么不更新了,是不是不刷题了,真是惭愧啊,题还是在刷的,不过刷题的频率没以前高了,看完<算法导论>后感觉网上很多讨论的题目其实在导论中都已经有非常好的算法以 ...
- leetcode 169. Majority Element 多数投票算法(Boyer-Moore Majority Vote algorithm)
题目: Given an array of size n, find the majority element. The majority element is the element that ap ...
- Majority Element——算法课上的一道题(经典)
Given an array of size n, find the majority element. The majority element is the element that appear ...
- [LeetCode] Majority Element 求众数
Given an array of size n, find the majority element. The majority element is the element that appear ...
- ✡ leetcode 169. Majority Element 求出现次数最多的数 --------- java
Given an array of size n, find the majority element. The majority element is the element that appear ...
- LeetCode——Majority Element
在一个数组中找到主要的元素,也就是出现次数大于数组长度一半的元素.容易想到的方式就是计数,出现次数最多的就是majority element,其次就是排序,中间的就是majority element. ...
- LeetCode OJ 169. Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- LeetCode 169. Majority Element (众数)
Given an array of size n, find the majority element. The majority element is the element that appear ...
- LeetCode169:Majority Element(Hash表\位操作未懂)
题目来源: Given an array of size n, find the majority element. The majority element is the element that ...
随机推荐
- PHP安全过滤函数
在PHP中,有些很有用的函数开源非常方便的防止你的网站遭受各种攻击,例如SQL注入攻击,XSS(Cross Site Scripting:跨站脚本)攻击等. 1. mysql_real_escap ...
- <数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件
一.简单的泛型类和接口 当指定一个泛型类时,类的声明则包括一个或多个类型参数,这些参数被放入在类名后面的一对尖括号内. 示例一: package cn.generic.example; public ...
- zabbix(2-server-agent)
注意:以下步骤都是在LAMP配置之后进行的. 关于LAMP环境的简单快速搭建,见博客:http://afterdawn.blog.51cto.com/7503144/1923139 下面开始介绍在Ce ...
- 1-安装MQTT服务器(Windows),并连接测试
对于不知道MQTT的肯定会问MQTT是干什么的....... 现在我有一个项目需求, 看到这个项目第一想法肯定需要一个服务器,所有的wifi设备和手机都去连接这个服务器,然后服务器进行信息的中转,类似 ...
- day69
昨日回顾: 1 路由层: 1简单配置 2无名分组 3有名分组 4反向解析--模板层,视图层 5路由分发 include 6名称空间 7伪静态 2 作业: urlpatterns = ...
- dirname(__FILE__) === __DIR__
dirname(__FILE__) === __DIR__get_class($this) == __CLASS__
- 2017-2018-2 20155230《网络对抗技术》实验5:MSF基础应用
基础问题回答 用自己的话解释什么是exploit,payload,encode. exploit 就是运行该模块吧,在msf的模块中配置好各项属性后exploit一下就开始运行使用该模块了 paylo ...
- 20155334 《网络攻防》Exp4 恶意代码分析
<网络攻防>Exp4 恶意代码分析 一.实验问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监 ...
- C++自学成长之路(第一篇)
今天开始我将开启C++自学成长之路,今天是第一天,在以前就一直在网上查找关于c++的资料,想买一本好一点的,权威一点的资料书,通过努力查找,我选择了c++ primer,在网上这本书的好评如潮.更多的 ...
- 腾讯云CVM服务器怎么建网站
腾讯云云服务器CVM站在用户的角度看就相当于一台计算机,虽然实际上它是一个虚拟服务器,是一个大的云端服务器集群虚拟出来的一个虚拟服务器,在使用上直接当做一个实际的服务器即可.那么,对于一个新手菜鸟来说 ...