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算法的更多相关文章

  1. 【算法31】寻找数组的主元素(Majority Element)

    题外话 最近有些网友来信问我博客怎么不更新了,是不是不刷题了,真是惭愧啊,题还是在刷的,不过刷题的频率没以前高了,看完<算法导论>后感觉网上很多讨论的题目其实在导论中都已经有非常好的算法以 ...

  2. 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 ...

  3. Majority Element——算法课上的一道题(经典)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  4. [LeetCode] Majority Element 求众数

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  5. ✡ leetcode 169. Majority Element 求出现次数最多的数 --------- java

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  6. LeetCode——Majority Element

    在一个数组中找到主要的元素,也就是出现次数大于数组长度一半的元素.容易想到的方式就是计数,出现次数最多的就是majority element,其次就是排序,中间的就是majority element. ...

  7. LeetCode OJ 169. Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  8. LeetCode 169. Majority Element (众数)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  9. LeetCode169:Majority Element(Hash表\位操作未懂)

    题目来源: Given an array of size n, find the majority element. The majority element is the element that ...

随机推荐

  1. 包、继承、Super、方法重写

    1 包_继承 1.1 包 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包可以看出目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维护 [ ...

  2. rest_framework源码分析

    CBV&APIView '''原生django as_view方法''' class View(object): http_method_names = ['get', 'post', 'pu ...

  3. 节点的启动与关闭 ros::init()解析(c++)

    1.初始化roscpp 节点 ros::init()  API链接:http://docs.ros.org/api/roscpp/html/init_8h.html 在node代码中在调用其它rosc ...

  4. Python2.7-collections

    collections 模块主要提供了五种特殊类型容器,此外还提供了许多抽象基类用于检查类的接口 1.Counter 对象,主要用于统计出现次数,是dict的一个子类,用法与形式和 dict 很类似 ...

  5. JAVA框架Struts2 servlet API

    一:servlet API 1)完全解耦接口: 使用ActionContext类进行相关操作: package jd.com.actioncontex; import com.opensymphony ...

  6. JavaScript HTML DOM,BOM

    DOM DOM 是一个 W3C (万维网联盟) 标准. DOM 定义了用于访问文档的标准: "W3C 文档对象模型 (DOM) 是一个平台和与语言无关的界面, 允许程序和脚本动态访问和更新文 ...

  7. 从CMDB动态获取服务器列表,按照Ansible的约定

    目标效果: [root@ansible ~]# python query.py --list{ "test": [ "10.1.2.1", "10.1 ...

  8. MVC的BundleConfig类

    在BundleConfig.cs文件中,包含了一些应用程序中使用的脚本和样式表的文件路径.并可以使用通配符.示例如下: using System.Web; using System.Web.Optim ...

  9. BZOJ 3812 : 主旋律

    非常神仙的状压DP+容斥原理. 首先,给出一个状压方程:$f_S$表示点集为$S$的情况下,整个点集构成强连通图的方案数. 这个DP方程还是比较容易想到的,但是没有办法正常转移,考虑通过容斥原理进行转 ...

  10. [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治

    Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...