绝对众数的求法
2016-07-21 14:43
218 查看
绝对众数是指在数列 p中出现次数严格大于|p|/2的数。
求绝对众数的几种方法:
(1)快速排序
快速排序之后在数列中间的数是绝对众数
(2)摩尔投票法
摩尔投票法的基本思想很容易理解,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。循环执行这一操作,直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半(无绝对众数)。如果只存在一种元素,那么这个元素则可能为绝对众数。
在编写算法的过程中,我们可以直接按照数组原来的顺序进行投票,删除。
具体实现:设 num为当前出现阶段超过半数的元素(候选数),cnt 为此元素出现次数。由于有了阶段的概念,这其实这也是一种动态规划思想。
一开始 num 直接为数组第一个元素, cnt=1。(原因是只有一个元素的数组,唯一的那个元素一定是绝对众数)
接着遍历数列 p,设当前数为k。
若 k=num,则 cnt+1。
若k≠num,则我们可以把当前候选数和当前数同时删除,具体操作就是让cnt−1,这样就相当于忽略了数k,删去一个num。
若cnt=0,表明前一阶段并没有出现次数超过半数的元素。假设绝对众数存在,那么绝对众数一定在剩余的数组中是绝对众数,这样我们只需要求解原始问题的子问题即可,即在后一阶段的绝对众数是多少。回到开始,num 为当前元素,cnt=1。
最终,若cnt>0,则num 可能为候选元素。扫一遍数组确认一下即可。
复杂度为线性的,O(n)。
求绝对众数的几种方法:
(1)快速排序
快速排序之后在数列中间的数是绝对众数
(2)摩尔投票法
摩尔投票法的基本思想很容易理解,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。循环执行这一操作,直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半(无绝对众数)。如果只存在一种元素,那么这个元素则可能为绝对众数。
在编写算法的过程中,我们可以直接按照数组原来的顺序进行投票,删除。
具体实现:设 num为当前出现阶段超过半数的元素(候选数),cnt 为此元素出现次数。由于有了阶段的概念,这其实这也是一种动态规划思想。
一开始 num 直接为数组第一个元素, cnt=1。(原因是只有一个元素的数组,唯一的那个元素一定是绝对众数)
接着遍历数列 p,设当前数为k。
若 k=num,则 cnt+1。
若k≠num,则我们可以把当前候选数和当前数同时删除,具体操作就是让cnt−1,这样就相当于忽略了数k,删去一个num。
若cnt=0,表明前一阶段并没有出现次数超过半数的元素。假设绝对众数存在,那么绝对众数一定在剩余的数组中是绝对众数,这样我们只需要求解原始问题的子问题即可,即在后一阶段的绝对众数是多少。回到开始,num 为当前元素,cnt=1。
最终,若cnt>0,则num 可能为候选元素。扫一遍数组确认一下即可。
复杂度为线性的,O(n)。
int findMajority(vector<int> nums){ int num=nums[0]; int k=0; for(int i=1;i<nums.size();i++){ if(nums[i]==num) k++; else if(nums[i]!=num&&k>0){ k--; } else if(nums[i]!=num&&k==0){ num=nums[i]; k=0 } } return num }
相关文章推荐
- 基于RBAC的saas权限系统设计
- poj 3461Oulipo
- 三阶魔方教程
- ANDROID SHAPE画圆形背景实现圆形TextView
- 谈谈javascript的Function中那些隐藏的属性/方法:caller/callee/apply/call/bind
- Java学习之路:不走弯路,就是捷径
- 安卓多线程之异步任务类解决子线程无法返回数据
- cookie和session
- 除非你是BAT,前端开发中最好少造轮子
- Windows环境下安装Redis
- FIFO管道通信(linux)
- .net/c#常用框架/中间件简介(不定时更新)
- cc2530启动流程---广播发送数据
- 简易画板-保存文件-刷新图库
- adb通过网络连接
- 正则表达式全部符号解释
- webpack 入门指南
- 内核探测工具systemtap简介
- jQuery.validate 中文API
- HashTable、HashMap、TreeMap梳理