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. centos 7 安装jira 破解

    http://blog.csdn.net/itjinglun/article/details/52240479

  2. 使用 zTree 右键菜单功能的总结

     一: 首先什么是zTree? zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点.专门适合项目开发,尤其是 树状菜单.树状 ...

  3. java中sleep()方法的解析

    Thread.sleep(3000); 就是指让当前正在运行的占用cpu时间片的线程挂起3000ms,把cpu的时间片交给其他线程,但是并没有指定把CPU的时间片接下来到底交给哪个线程,而是让这些线程 ...

  4. 在 ASP.NET CORE 中使用 SESSION (转载)

    Session 是保存用户和 Web 应用的会话状态的一种方法,ASP.NET Core 提供了一个用于管理会话状态的中间件.在本文中我将会简单介绍一下 ASP.NET Core 中的 Session ...

  5. TF-IDF算法-golang实现

    1.TF-IDF算法介绍 TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrie ...

  6. 遍历目录删除指定MD5值的文件

    工作需要实现一个查找出指定目录下md5值与excel表格中md5值相同的文件然后删掉的功能.我是这样做的:首先遍历指定目录,计算该目录下所有文件的md5值,以文件路径为key,md5值为value保存 ...

  7. Android下so注入汇总

    /**  作者:蟑螂一号*  原文链接:http://www.sanwho.com/133.html*  转载请注明出处*/ Android下so注入是基于ptrace系统调用,因此要想学会andro ...

  8. Exp02

    使用netcat后门工具 原理示意图 使用netcat获取主机操作Shell,cron启动 Win获取Linux Shell Linux获取Win Shell cron启动 用man -k指令查看有关 ...

  9. 2017-2018-1 20155331 嵌入式C语言

    2017-2018-1 20155331 嵌入式C语言 作业要求: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案,还是找别人要答案都清零) ...

  10. flask 与 vue.js 2.0 实现 todo list

    实现了后端与前端分离,后端提供 RESTful api. 后端 flask 与前端 vue 的数据传输都是 json. 本文使用 vue.js 2.0 对前一个例子:flask, SQLAlchemy ...