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 ...
随机推荐
- 包、继承、Super、方法重写
1 包_继承 1.1 包 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包可以看出目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维护 [ ...
- rest_framework源码分析
CBV&APIView '''原生django as_view方法''' class View(object): http_method_names = ['get', 'post', 'pu ...
- 节点的启动与关闭 ros::init()解析(c++)
1.初始化roscpp 节点 ros::init() API链接:http://docs.ros.org/api/roscpp/html/init_8h.html 在node代码中在调用其它rosc ...
- Python2.7-collections
collections 模块主要提供了五种特殊类型容器,此外还提供了许多抽象基类用于检查类的接口 1.Counter 对象,主要用于统计出现次数,是dict的一个子类,用法与形式和 dict 很类似 ...
- JAVA框架Struts2 servlet API
一:servlet API 1)完全解耦接口: 使用ActionContext类进行相关操作: package jd.com.actioncontex; import com.opensymphony ...
- JavaScript HTML DOM,BOM
DOM DOM 是一个 W3C (万维网联盟) 标准. DOM 定义了用于访问文档的标准: "W3C 文档对象模型 (DOM) 是一个平台和与语言无关的界面, 允许程序和脚本动态访问和更新文 ...
- 从CMDB动态获取服务器列表,按照Ansible的约定
目标效果: [root@ansible ~]# python query.py --list{ "test": [ "10.1.2.1", "10.1 ...
- MVC的BundleConfig类
在BundleConfig.cs文件中,包含了一些应用程序中使用的脚本和样式表的文件路径.并可以使用通配符.示例如下: using System.Web; using System.Web.Optim ...
- BZOJ 3812 : 主旋律
非常神仙的状压DP+容斥原理. 首先,给出一个状压方程:$f_S$表示点集为$S$的情况下,整个点集构成强连通图的方案数. 这个DP方程还是比较容易想到的,但是没有办法正常转移,考虑通过容斥原理进行转 ...
- [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...